Tayeb Chlyah es un arquitecto principal de Java con una sólida experiencia en aplicaciones de rendimiento a gran escala, microservicios y bases de datos NoSQL. Ha desarrollado un par de bibliotecas Java de código abierto para Couchbase.
Introducción
Todo desarrollador de éxito necesita estar al día de las nuevas tecnologías punteras y las tendencias emergentes, probarlas, jugar con ellas, ver si pueden encajar en un proyecto y cómo puede mejorarlas.
Pero, ¿cómo lograrlo en un mundo en rápida evolución en el que cada día nacen nuevas tecnologías y marcos de trabajo?
Si eres un desarrollador Java full-stack, tienes mucha suerte: JHipster es la solución para aprehender rápidamente las nuevas tecnologías de la mejor manera. Es un Generador YeomanSpring Boot, un sistema de andamiaje, que te ayuda a generar aplicaciones completas combinando uno de los mejores frameworks en desarrollo web: Spring Boot backend y Angular o React frontend.
Por supuesto, puede utilizar Primavera Initialzro implementarlo todo por ti mismo, pero implementar con éxito esas combinaciones no es nada trivial. Hay que dedicar mucho tiempo a estudiar cada concepto, y luego intentar pegarlo todo, sin olvidar las pruebas, lo que puede ser muy costoso y propenso a errores. Y sobre todo, puede desanimarte o, en el mejor de los casos, obligarte a centrarte en uno de los frameworks.
JHipster construye aplicaciones totalmente probadas de forma rápida y sencilla, utilizando las mejores prácticas, metodologías y estrategias. Propone muchas opciones (Arquitectura - monolito o microservicios; Base de datos - SQL o NoSQL; Seguridad - autenticación de sesión, JWT u OAuth2; Otros - WebSocket, cachés, Docker, Kubernetes ...), que puede ayudarle a probar las mejores tecnologías que existen, y elegir las combinaciones más adecuadas para su caso de uso.
Hoy vamos a centrarnos en algunos de los nuevos conceptos arquitectónicos más importantes: microservicios y NoSQL con Couchbase.
¿Por qué Couchbase?
Couchbase es una base de datos NoSQL orientada a documentos. Con las bases de datos de documentos, tienes un diseño sin esquemas que te permite cambiar tus datos libre y fácilmente. También puedes almacenar toda la estructura en un único documento, evitando muchas uniones innecesarias, lo que se traduce en operaciones de lectura y escritura naturalmente más rápidas.
Couchbase expone un rápido almacén de claves y valores y un potente motor de consultas junto con indexadores integrados para consultar datos con N1QL, un lenguaje similar a SQL para documentos JSON. Gracias a su arquitectura distribuida sin maestros, es muy fácil de escalar. Puede realizar millones de operaciones por segundo sin necesidad de una caché de terceros. Couchbase también viene con búsqueda de texto completo integrada, un motor de análisis y una solución móvil completa.
¿Por qué microservicios?
La arquitectura de microservicios es un patrón de desarrollo de sistemas de software que se centra en la creación de aplicaciones como un conjunto de servicios pequeños, modulares y poco acoplados, lo que permite una entrega continua más sencilla, una mejor capacidad de prueba, escalabilidad y un mejor aislamiento de fallos. Cada servicio puede estar escrito en diferentes lenguajes y puede utilizar diferentes técnicas de almacenamiento de datos, lo que permite la capacidad de organizar el desarrollo en torno a múltiples equipos de características.
Pero los microservicios conllevan algunos retos: descomponer la aplicación en servicios puede ser muy complicado y es todo un arte. Los desarrolladores también tienen que lidiar con la complejidad adicional de un sistema distribuido.
JHipster gestiona la mayor parte de las complejidades de los microservicios: Descubrimiento y configuración de servicios con Cónsul o Registro JHipster (Netflix Eureka, Servidor de configuración de Spring Cloudy panel de control), equilibrio de carga con Cinta Netflixtolerancia a fallos con Netflix Hystrixy registro y supervisión centralizados con jhipster-consola (pila personalizada de Elasticsearch, Logstash y Kibana), y mucho más.
Creación de un microservicio de cervecería
Requisitos previos:
- Instale Motor Docker
- Instale JDK 8
- Instale la versión LTS de 64 bits en Node.js
- Instale Hilo
- Instale JHipster:
yarn global add generador-jhipster
Generar una pasarela API
Para poder acceder a nuestros diferentes servicios en una arquitectura de microservicios, vamos a necesitar un Pasarela API. Es la entrada a sus microservicios. Proporciona enrutamiento HTTP (Netflix Zuul) y el equilibrio de carga (Cinta Netflix), la calidad de los servicios (Netflix Hystrix), seguridad (Seguridad en primavera) y la documentación de la API (Swagger) para todos los microservicios.
En una ventana de terminal:
1 2 3 4 5 |
mkdir couchbase-jhipster-microservicios-ejemplo cd couchbase-jhipster-microservicios-ejemplo mkdir pasarela cd pasarela jhipster |
JHipster te pregunta sobre el tipo de aplicación que quieres crear y qué características quieres incluir. Puedes encontrar todos los detalles sobre las opciones disponibles en Sitio web de JHipster. Utilice las siguientes respuestas para generar una pasarela compatible con Couchbase.
Generar una aplicación de microservicio de cervecería
En couchbase-jhipster-microservicios-ejemplocrear un cervecería y ejecute jhipster para generar un microservicio con base de datos Couchbase con las siguientes respuestas:
Generar entidades cerveceras
Crear un archivo cervecería.jh en couchbase-jhipster-microservicios-ejemplo con lo siguiente JDL (Lenguaje de dominio JHipster):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
entidad Cerveza { nombre Cadena obligatorio, categoría Cadena obligatorio, descripción Cadena, estilo Cadena, cervecería Cadena, abv Flotador, ibu Entero, srm Entero, upc Entero, actualizado FechaLocal } entidad Cervecería { nombre Cadena obligatorio, descripción Cadena, dirección Cadena obligatorio longitud máxima(200), ciudad Cadena, código Cadena, país Cadena, teléfono Cadena patrón(/[0-9- .]+/), estado Cadena, sitio web Cadena, actualizado FechaLocal } |
paginar Beer con paginador
paginar Cervecería con infinite-scroll
En una ventana de terminal, ejecute los siguientes comandos:
1 2 3 4 5 |
cd cervecería jhipster importar-jdl ../cervecería.jh cd ../pasarela jhipster entidad cervecería jhipster entidad cerveza |
Cuando se le pida que sobrescriba archivos, responda siempre a.
Ejecutar la arquitectura de microservicios
Para ejecutar nuestra arquitectura, necesitamos iniciar lo siguiente:
- Registro JHipster
- Keycloack: una solución de código abierto para la gestión de identidades y accesos
- Servidor Couchbase
- Microservicio de cervecería
- Pasarela
Afortunadamente, JHipster tiene un subgenerador docker-compose que iniciará todos los servicios necesarios sin quebraderos de cabeza. Pero primero, tenemos que construir nuestras aplicaciones. En couchbase-jhipster-microservicios-ejemplo:
1 2 3 4 5 6 |
cd pasarela ./mvnw paquete -Pprod archivo docker:construya -DskipTests cd ../cervecería ./mvnw paquete -Pprod archivo docker:construya -DskipTests cd .. mkdir docker-componer && cd docker-componer |
Ahora, podemos generar docker-compose.yml utilizando el siguiente comando y respuestas:
1 |
jhipster docker-componer |
Para que nuestra aplicación funcione con un keycloak local, tenemos que añadir a tu archivo hosts (Windows: C:\Windows\System32\drivers\etc\hostsMac/Linux: /etc/hosts) la línea siguiente:
1 |
127.0.0.1 keycloak |
Antes de iniciar todo, asegúrese de que ha configurado Docker con suficiente memoria y CPU, a continuación, ejecute:
1 |
docker-componer arriba |
Una vez que todo termine de arrancar, abre un navegador para Pasarela (http://localhost:8080/), haga clic en cuenta y, a continuación, inicie sesión.
Debería ser redirigido a keycloakInicie sesión con admin tanto para el usuario como para la contraseña.
Volverás a la pasarela, donde podrás ver las interfaces de administración, cambiar el idioma, ver y editar tus entidades...
Registro JHipster
Ahora abre tu navegador en http://localhost:8761/. Se iniciará sesión automáticamente puesto que ya lo has hecho en keycloak, que es la magia de la autenticación oauth2.
Además de ser la columna vertebral de su aplicación de microservicio, ya que es un servidor de descubrimiento con Eureka que se encarga del enrutamiento, el equilibrio de carga y la escalabilidad, y un servidor de configuración con Servidor de configuración de Spring Cloud que proporciona la configuración en tiempo de ejecución de sus aplicaciones, Registro JHipster es también un servidor de administración, donde puede visualizar las instancias de su aplicación, su estado, las métricas y los registros.
¿Cómo funciona?
Acceso a la base de datos
En primer lugar, necesita acceder a la instancia brewery-couchbase. Para ello, actualice docker-compose/docker-compose.yml para publicar su puerto de interfaz de administración con lo siguiente:
1 2 3 4 5 6 7 8 |
cervecería-couchbase: construya: contexto: ../cervecería/src/principal/docker archivo docker: couchbase/Couchbase.Dockerfile medio ambiente: - CUBO=cervecería puertos: - 8091:8091 |
Apliquemos nuestros cambios, en docker-compose directorio:
1 |
docker-componer arriba -d |
Cuando todo esté listo, abra la interfaz de administración de Couchbase en http://localhost:8091/e inicie sesión con Administrador como usuario y contraseña como contraseña. Abrir cubo cervecero Documentos.
Couchmove
Como puedes ver, tu cubo ya está poblado con algunos documentos: JHipster rellena los documentos de arranque usando Couchmoveuna biblioteca Java de migración de datos para Couchbase, ampliamente inspirada en Ruta de vueloya que favorece la simplicidad y la convención frente a la configuración.
Puede consultar los archivos de registro de cambios en
1 |
cervecería/src/principal/recursos/config/couchmove/registro de cambios directorio: |
- V0.1__configuración_inicial directorio: contiene documentos de usuario y autoridad, utilizados por Seguridad en primavera para autenticar a los usuarios.
- V0__create_indexes.n1qlcrea los índices necesarios.
Como Flyway o liquibase para bases de datos SQL, Couchmove mantiene registro de cambios documentos, haciendo un seguimiento de los registros de cambios ejecutados.
Spring Boot y Spring Data Couchbase
JHipster genera un Spring Boot 2 aplicación y usos Datos de primavera para acceder a bases de datos relacionales y no relacionales. En nuestro caso, se utiliza Spring Data Couchbase para proporcionar integración con la base de datos Couchbase Server. Pero va mucho más allá personalizando su funcionamiento:
Por defecto, Spring Data Couchbase utiliza N1qlCouchbaseRepository.java que aprovecha N1QL sólo para paginación u ordenación findAll operaciones. Todas las demás operaciones utilizan vistas como se puede ver en la implementación de SimpleCouchbaseRepository.java. Dado que siempre se accede a los índices de vistas desde el disco, no son tan performante.
Veamos cómo JHipster mejora este comportamiento:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Configuración @Perfil("!" + JHipsterConstants.SPRING_PROFILE_CLOUD) @EnableCouchbaseRepositories(repositoryBaseClass = CustomN1qlCouchbaseRepository.clase, basePackages = "com.couchbase.example.brewery.repository") @Importar(valor = CouchbaseAutoConfiguration.clase) @EnableCouchbaseAuditing(auditorAwareRef = "springSecurityAuditorAware") público clase Configuración de la base de datos { ... @Judía público Couchmove couchmove(Cubo couchbaseBucket) { registro.depurar("Configurar Couchmove"); Couchmove couchMove = nuevo Couchmove(couchbaseBucket, "config/couchmove/changelog"); couchMove.migrar(); devolver couchMove; } ... } |
Configuración de la base de datos configura e inicia las migraciones de Couchmove, y también habilita los repositorios de Couchbase pero con una clase base personalizada: CustomN1qlCouchbaseRepository
1 2 3 4 5 6 7 8 |
público clase CustomN1qlCouchbaseRepository<T, ID extiende Serializable> extiende N1qlCouchbaseRepository<T, ID> { ... @Anular público <S extiende T> S guardar(S entidad) { devolver super.guardar(populateIdIfNecessary(entidad)); } ... } |
Esta clase extiende el repositorio por defecto para auto-generar el ID del documento antes de guardarlo, y habilita el uso de N1QL para todas las operaciones implementando CustomN1qlRespository interfaz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@NoRepositoryBean público interfaz N1qlCouchbaseRepository<T, ID extiende Serializable> extiende CouchbasePagingAndSortingRepository<T, ID> { @Consulta("#{#n1ql.selectEntity} WHERE #{#n1ql.filter}") Lista<T> findAll(); @Consulta("SELECT count(*) FROM #{#n1ql.bucket} WHERE #{#n1ql.filter}") largo cuente(); @Consulta("DELETE FROM #{#n1ql.bucket} WHERE #{#n1ql.filter} returning #{#n1ql.fields}") T removeAll(); por defecto void deleteAll() { removeAll(); } } |
Los identificadores se generan automáticamente mediante Valor generado con un prefijo IdPrefix que por defecto es el nombre de la clase, separado por __ delimitador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Documento público clase Cervecería implementa Serializable { privado estático final largo serialVersionUID = 1L; público estático final Cadena PREFIX = "cervecería"; @SuprimirAviso("sin usar") @IdPrefix privado Cadena prefijo = PREFIX; @Id @Valor generado(estrategia = ÚNICO, delimitador = ID_DELIMITADOR) privado Cadena id; ... } |
Pruebas
Hemos dicho antes que las aplicaciones generadas por JHipster se prueban completamente con pruebas unitarias y de pruebas de integración¿pero cómo funciona para los de integración?
Para Couchbase, utiliza Couchbase testContainersque es un módulo que amplía contenedores de pruebauna librería Java que facilita el lanzamiento de cualquier contenedor Docker durante la duración de las pruebas JUnit, con el fin de iniciar automáticamente una instancia de Couchbase Server, y configurarlo con los servicios, usuarios, buckets e índices necesarios.
Para ejecutar las pruebas, ejecute el siguiente comando en una ventana de terminal:
1 |
./mvnw limpiar prueba |
Rellenar algunos datos
Para rellenar algunos datos, utilizaremos Couchbase Cubos de muestra. Abrir Ajustes ficha, Cubos de muestraa continuación, seleccione la muestra de cerveza y haga clic en Cargar datos de muestra.
Es necesario dar forma a los datos en Spring Data Couchbase formato de serialización. Para ello, abra la pestaña Consulta y ejecute las siguientes consultas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
INSERTAR EN cervecería (CLAVE k, VALOR v) SELECCIONE tipo || "__" || meta().id como k, { "nombre": nombre, "categoría": categoría, "descripción": descripción, "estilo": estilo, "cervecería": brewery_id, "abv": abv, "ibu": ibu, "srm": srm, "upc": upc, "actualizado": STR_TO_MILLIS(actualizado), "_clase" : "com.couchbase.example.brewery.domain.Beer" } como v DESDE `cerveza-muestra` DONDE tipo = cerveza; INSERTAR EN cervecería (CLAVE k, VALOR v) SELECCIONE tipo || "__" || meta().id como k, { "nombre": nombre, "descripción": descripción, "dirección": dirección[0], "país": país, "sitio web": sitio web, "código": código, "ciudad": ciudad, "teléfono": teléfono, "estado": estado, "actualizado": STR_TO_MILLIS(actualizado), "_clase" : "com.couchbase.example.brewery.domain.Brewery" } como v DESDE `cerveza-muestra` DONDE tipo = cervecería; |
He aquí un ejemplo de documento de cerveza insertado:
Ahora veamos cómo JHipster maneja los documentos recién insertados. Navegue a Pasarela, Entidadesa continuación, abra Cervecería. JHipster carga primero 20 cervecerías, y si te desplazas hacia abajo, ¡carga más! Propone navegación por páginas para Cerveza porque elegimos este comportamiento al generar entidades con cervecería.jh JDL.
1 2 |
paginar Cerveza con localizador paginar Cervecería con infinito-desplazarse |
Código fuente
El código fuente de las aplicaciones generadas está disponible en tchlyah/couchbase-jhipster-microservicios-ejemplo.
¿Y ahora qué?
JHipster, con la ayuda de Elasticsearch, propone una opción que añade funciones de búsqueda sobre la base de datos. Pero Couchbase tiene un out-of-the-box Búsqueda de texto completo que ofrece amplias posibilidades de consulta en lenguaje natural. ¿Por qué no implementar ese soporte en JHipster? Si puedes ayudarnos, no dudes en contribuir!
Si tienes alguna pregunta, envíame un tweet a @tchlyah o deje un comentario a continuación.