Los contenedores, los microservicios y NoSQL proporcionan un trío impresionante para crear aplicaciones modernas. Estas aplicaciones deben ser ágiles, satisfacer las demandas de los clientes en constante evolución, ser omnipresentes y funcionar en plataformas móviles, web e IoT.
Este blog explicará una sencilla pila de microservicios utilizando Enjambre WildFly, Dockery Couchbase. El código completo y las instrucciones de este blog están documentados en: github.com/arun-gupta/wildfly-swarm-couchbase.
Entendamos primero los componentes clave de esta pila.
Enjambre WildFly permite empaquetar y ejecutar aplicaciones JavaEE empaquetándolas con lo justo del tiempo de ejecución del servidor para
java -jar
su aplicación. Con el descubrimiento de servicios integrado, inicio de sesión único con Keycloak, supervisión mediante Hawkulary muchas más características, WildFly Swarm proporciona todos los componentes necesarios para desarrollar su microservicio.
Docker para Mac proporciona soporte nativo para ejecutar contenedores Docker en Mac OSX. Se basa en Hipervisor.framework
en OSX. El motor Docker se ejecuta en una distribución Linux Alpine sobre un xhyve
Máquina Virtual, e incluso la VM es gestionada por Docker. No hay necesidad de Docker Machine o VirtualBox, y se integra con el modelo sandbox de seguridad de OSX. DockerCon 2016 eliminó la restricción de beta privada de Docker para Mac, por lo que ya está disponible para todo el mundo.
NoSQL ofrece la agilidad y flexibilidad de las bases de datos sin esquema. Esto permite que la aplicación evolucione de forma independiente y rápida sin pasar por engorrosas migraciones de bases de datos. Couchbase ofrece un verdadero escalado horizontal con arquitectura homogéneaa diferencia de la arquitectura maestro/esclavo no escalable. También ofrece auto-sharding, Lenguaje de consulta tipo SQL para JSON (N1QL), base de datos móvil y sincronización con el servidor backend, y mucho más. La aplicación de ejemplo completa en este blog está en: github.com/arun-gupta/wildfly-swarm-couchbase.
Aplicación WildFly Swarm
Veamos el punto final REST de Java EE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
paquete com.couchbase.mosca salvaje.enjambre; . . . @Ruta("aerolínea") público clase AerolíneaRecurso { @Inyectar Base de datos base de datos; @GET público Cadena getAll() { N1qlQuery consulta = N1qlQuery.simple("SELECT * FROM `viaje-muestra` LIMIT 10"); N1qlQueryResultado resultado = base de datos.getBucket().consulta(consulta); devolver resultado.allRows().toString(); } . . . } |
Utiliza la anotación JAX-RS estándar para convertir un POJO en un endpoint REST. API Java de Couchbase proporcionan una API fluida y utilizan la sentencia N1QL para consultar los documentos y devolver los resultados. La sentencia N1QL devuelve los 10 primeros elementos del resultado de la consulta. Aprenda más sobre la sintaxis N1QL en este tutorial interactivo. La abstracción de la base de datos se define como:
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 |
paquete com.couchbase.mosca salvaje.enjambre; . . . @Singleton @Puesta en marcha público clase Base de datos { CouchbaseCluster grupo; Cubo cubo; público CouchbaseCluster getCluster() { si (null == grupo) { Cadena couchbaseURI = Sistema.getenv("COUCHBASE_URI"); si (null == couchbaseURI) { Sistema.err.println("WARING: No COUCHBASE_URI specified, defaulting to localhost"); couchbaseURI = "localhost:8093"; } Sistema.fuera.println("Punto final de Couchbase: " + Sistema.getenv("COUCHBASE_URI")); grupo = CouchbaseCluster.crear(couchbaseURI); } devolver grupo; } público Cubo getBucket() { si (null == cubo) { cubo = getCluster().openBucket("viaje-muestra"); } devolver cubo; } } |
Se trata de un EJB singleton que se inicializa por anticipado. Utiliza SDK Java de Couchbase para conectarse a Couchbase. El punto final de la base de datos se puede especificar utilizando el parámetro COUCHBASE_URI
variable de entorno. El siguiente paso es pom.xml
para configurar WildFly Swarm y Cliente Java de Couchbase:
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 |
org.mosca salvaje.enjambre bom ${versión.mosca salvaje-enjambre} pom importar javax javaee-web-api 7.0 proporcionado org.mosca salvaje.enjambre jaxrs-cdi org.mosca salvaje.enjambre ejb com.couchbase.cliente java-cliente 2.2.5 |
Utiliza la "lista de materiales" de WildFly Swarm para extraer todas las dependencias. Sólo las dependencias específicas necesarias para la compilación se especifican en . A continuación, se empaquetan en el "fat jar". El plugin Maven de WildFly Swarm se utiliza para empaquetar y ejecutar la aplicación:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
org.mosca salvaje.enjambre mosca salvaje-enjambre-plugin ${versión.mosca salvaje-enjambre} paquete ${COUCHBASE_URI} |
COUCHBASE_URI
se utiliza para leer el host donde se ejecuta el servidor de base de datos Couchbase.
Ejecutar Couchbase Server
Ejecute el servidor Couchbase utilizando Docker para Mac:
1 |
docker ejecute -d --nombre db -p 8091-8093:8091-8093 -p 11210:11210 arungupta/couchbase |
En arungupta/couchbase
se basa en el imagen estándar de Couchbase y utiliza API REST de Couchbase para configurar el servidor. Espere un par de minutos a que el bucket de muestra se rellene con los documentos JSON. Ejecute la aplicación Herramienta CLI de Couchbase cbq crear un índice primario en el bucket de muestra:
1 |
docker ejecute -it --enlace db:db arungupta/couchbase cbq -u Administrador -p contraseña -motor http://db:8093 -s "create primary index `travel-sample-primary-index` on `travel-sample`;" |
Esto mostrará la salida como:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Conectado a : http://db:8093/. Teclee Ctrl-D o QUIT para salir. Ruta a historia archivo para el concha : /raíz/.cbq_historia { "requestID": "d0b2e4dd-b702-49e2-971c-a4c640ddb498", "firma": null, "resultados": [ ], "status": "éxito", "métricas": { "tiempo transcurrido": "3.154540272s", "executionTime": "3.154493281s", "resultCount": 0, "resultSize": 0 } } |
Esta salida muestra que el resultado de la creación del índice fue exitoso. Una de las ventajas de ejecutar Docker para Mac es que todos los contenedores son accesibles en localhost
. Es decir Consola web de Couchbase puede consultarse en localhost:8091.
Esta pantalla asegura que Couchbase está configurado correctamente.
Ejecutar el microservicio WildFly Swarm
Empaqueta y ejecuta el microservicio autónomo como:
1 |
mvn mosca salvaje-enjambre:ejecute |
Si Couchbase se está ejecutando en un host diferente, entonces el comando cambiará a:
1 |
mvn -DCOUCHBASE_URI= mosca salvaje-enjambre:ejecute |
Muestra la salida como:
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 |
[INFO] Escaneado para proyectos... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Edificio nosql-microservicios 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] . . . 2016-06-27 22:21:47,170 AVISO [org.jboss.como.dependencia.privado] (MSC servicio hilo 1-6) WFLYSRV0018: Despliegue "deployment.nosql-microservices.war" es utilizando a privado módulo ("org.jboss.jts:main") que mayo sea cambiado o eliminado en futuro versiones sin aviso. 2016-06-27 22:21:47,203 INFO [org.jboss.soldar.desplegador] (MSC servicio hilo 1-1) WFLYWELD0003: Tratamiento soldar despliegue nosql-microservicios.guerra 2016-06-27 22:21:47,542 INFO [org.hibernar.validador.interno.util.Versión] (MSC servicio hilo 1-1) HV000001: Hibernar Validador 5.2.3.Final 2016-06-27 22:21:47,600 INFO [org.jboss.como.ejb3.despliegue] (MSC servicio hilo 1-1) WFLYEJB0473: JNDI fijaciones para sesión judía llamado Base de datos en despliegue unidad 'deployment "nosql-microservices.war"' son como sigue: java:global/nosql-microservicios/Base de datos!com.couchbase.mosca salvaje.enjambre.Base de datos java:aplicación/nosql-microservicios/Base de datos!com.couchbase.mosca salvaje.enjambre.Base de datos java:módulo/Base de datos!com.couchbase.mosca salvaje.enjambre.Base de datos java:global/nosql-microservicios/Base de datos java:aplicación/nosql-microservicios/Base de datos java:módulo/Base de datos 2016-06-27 22:21:47,731 INFO [org.jboss.soldar.desplegador] (MSC servicio hilo 1-3) WFLYWELD0006: Inicio Servicios para CDI despliegue: nosql-microservicios.guerra 2016-06-27 22:21:47,758 INFO [org.jboss.soldar.Versión] (MSC servicio hilo 1-3) SOLDADURA-000900: 2.3.2 (Final) 2016-06-27 22:21:47,780 INFO [org.mosca salvaje.extensión.resaca] (MSC servicio hilo 1-1) WFLYUT0018: Anfitrión por defecto-host Inicio 2016-06-27 22:21:47,788 INFO [org.jboss.soldar.desplegador] (MSC servicio hilo 1-8) WFLYWELD0009: Inicio soldar servicio para despliegue nosql-microservicios.guerra 2016-06-27 22:21:48,180 INFO [stdout] (ServicioServidor Hilo Piscina -- 10) Couchbase punto final: 2016-06-27 22:21:48,275 INFO [com.couchbase.cliente.núcleo.CouchbaseCore] (ServicioServidor Hilo Piscina -- 10) CouchbaseEnvironment: {sslEnabled=falso, sslKeystoreFile=null, sslKeystorePassword=null, queryEnabled=falso, queryPort=8093, bootstrapHttpEnabled=verdadero, bootstrapCarrierEnabled=verdadero, bootstrapHttpDirectPort=8091, bootstrapHttpSslPort=18091, bootstrapCarrierDirectPort=11210, bootstrapCarrierSslPort=11207, ioPoolSize=8, computationPoolSize=8, responseBufferSize=16384, requestBufferSize=16384, kvServiceEndpoints=1, viewServiceEndpoints=1, queryServiceEndpoints=1, searchServiceEndpoints=1, ioPool=NioEventLoopGroup, coreScheduler=CoreScheduler, eventBus=DefaultEventBus, packageNameAndVersion=couchbase-jvm-núcleo/1.2.5 (git: 1.2.5), dcpEnabled=falso, retryStrategy=BestEffort, maxRequestLifetime=75000, retryDelay=Retardo exponencial{growBy 1.0 MICROSEGUNDOS, poderes de 2; inferior=100, superior=100000}, reconnectDelay=Retardo exponencial{growBy 1.0 MILLISEGUNDOS, poderes de 2; inferior=32, superior=4096}, observeIntervalDelay=Retardo exponencial{growBy 1.0 MICROSEGUNDOS, poderes de 2; inferior=10, superior=100000}, keepAliveInterval=30000, autoreleaseAfter=2000, bufferPoolingEnabled=verdadero, tcpNodelayEnabled=verdadero, mutationTokensEnabled=falso, socketConnectTimeout=1000, dcpConnectionBufferSize=20971520, dcpConnectionBufferAckThreshold=0.2, queryTimeout=75000, viewTimeout=75000, kvTimeout=2500, connectTimeout=5000, disconnectTimeout=25000, dnsSrvEnabled=falso} 2016-06-27 22:21:48,829 INFO [com.couchbase.cliente.núcleo.nodo.Nodo] (cb-io-1-1) Conectado a Nodo localhost 2016-06-27 22:21:49,035 INFO [com.couchbase.cliente.núcleo.config.ConfigurationProvider] (cb-cálculos-1) Abierto cubo viaje-muestra 2016-06-27 22:21:49,415 INFO [org.jboss.descansa.resteasy_jaxrs.i18n] (ServicioServidor Hilo Piscina -- 10) RESTEASY002225: Despliegue de javax.ws.rs.núcleo.Aplicación: clase com.couchbase.mosca salvaje.enjambre.MiAplicación 2016-06-27 22:21:49,438 INFO [org.mosca salvaje.extensión.resaca] (ServicioServidor Hilo Piscina -- 10) WFLYUT0021: Registrado web contexto: / 2016-06-27 22:21:49,457 INFO [org.jboss.como.servidor] (principal) WFLYSRV0010: Desplegado "nosql-microservicios.war" (tiempo de ejecución-nombre : "nosql-microservicios.war") |
Ahora se puede acceder a la aplicación como:
1 |
rizo http://localhost:8080/webresources/airline |
Y una salida formateada tiene este aspecto:
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 |
[ { "viaje-muestra": { "país": "Estados Unidos", "iata": "Q5", "Indicativo": "MILE-AIR", "nombre": "40-Mile Air", "icao": "MLA", "id": 10, "tipo": "aerolínea" } }, . . . { "viaje-muestra": { "país": "Francia, "iata": "A5", "Indicativo": "AIRLINAIR", "nombre": "Airlinair", "icao": "RLA", "id": 1203, "tipo": "aerolínea" } } ] |
Así que has construido un microservicio simple usando WildFly Swarm accediendo a una base de datos Couchbase ejecutándose como un contenedor Docker. Ahora, idealmente este servicio WildFly Swarm debería ser empaquetado como una imagen Docker y luego esa imagen Docker serviría como el servicio. Un perfil de Maven con el nombre docker
ya se ha añadido a pom.xml
pero número #3 está haciendo fracasar ese escenario.