Ir al contenido

Aprendiendo microservicios con un ejemplo práctico

·705 palabras·4 mins
Programación
Alejandro Duarte
Autor
Alejandro Duarte
Alejandro Duarte es un Ingeniero de Software, escritor publicado y galardonado. Actualmente, trabaja para MariaDB plc como Ingeniero de Relaciones con Desarrolladores (Developer Relations Engineer). Comenzó su trayectoria en programación a los 13 años con BASIC en una rudimentaria pantalla negra, para lugo rápidamente transitar a C, C++ y Java durante sus años académicos en la Universidad Nacional de Colombia. Trasladándose primero al Reino Unido y luego a Finlandia, Alejandro profundizó su participación en la comunidad de código abierto. Es reconocido en los círculos de Java, acreditado con artículos y videos que acumulan millones de vistas, y presentaciones en eventos internacionales.

Aunque esta aplicación de ejemplo es simplista y nadie debería usar microservicios para implementar una aplicación como esta, te muestra cómo se siente ejecutar este tipo de aplicaciones y cómo implementarla usando Spring Cloud.

Si solo quieres jugar con una aplicación de microservicios, sigue este tutorial. Si quieres implementar la aplicación completa usando Java, Eureka, Spring Cloud Config, Spring Data Rest, Hystrix, Zuul, Spring Session y Vaadin,  sigue el tutorial completo de 9 pasos. Después de completar el tutorial, terminarás con varios terminales, cada una ejecutando un servicio específico:

Ejecutando microservicios

En proyectos reales, seguro que no ejecutarías microservicios de esta forma, sino que usarías una herramienta de orquestación como Docker Swarm o Kubernetes. Hay una rama en el repositorio de la aplicación de ejemplo que contiene archivos Docker con los que podrías experimentar para aprender más sobre cómo desplegar microservicios en entornos de producción.

En las siguientes secciones, describo algunas pautas para crear un entorno de práctica.

Configura las máquinas
#

Usa VirtualBox para crear una máquina virtual e instalar Alpine Linux en ella. Utiliza un Bridged Adapter en la configuración de red.

Configura IPs estáticas para ambas máquinas. Edita el archivo /etc/network/interfaces así:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.150
        netmask 255.255.255.0
        gateway 192.168.1.1

Configura SSH para que puedas usar tu máquina anfitriona a partir de ahora para conectarte a la máquina virtual (algo que ocurriría en un escenario real):

apk add openssh

Necesitarás agregar PermitRootLogin yes al archivo /etc/ssh/sshd_config para facilitar las cosas por ahora (o puedes crear un nuevo usuario de SO y conectarte a la VM usando sus credenciales). Con esto, puedes conectarte a la VM así:

Para instalar Docker, primero agrega el siguiente repositorio al archivo /etc/apk/repositories:

http://dl-cdn.alpinelinux.org/alpine/latest-stable/community

Luego ejecuta:

apk update
apk add docker

Para ejecutar Docker al inicio (boot), ejecuta:

rc-update add docker boot

En VirtualBox, apaga la VM y clónala. Genera una nueva dirección MAC para la VM clonada en la configuración de red. Inicia y conéctate a la VM clonada para configurar una dirección IP diferente en el archivo /etc/network/interfaces. Por ejemplo, 192.168.1.151. Reinicia la VM clonada y arranca la original. Ahora deberías tener dos VM listas.

Ejecutan la aplicación con Docker Swarm
#

En la máquina 192.168.1.150, inicia un swarm:

docker swarm init --advertise-addr 192.168.1.150

Esta máquina es ahora el máster del swarm.

Copia el comando de unión al Docker swarm reportado (join) y ejecútalo en la otra máquina (192.168.1.151). El comando debería parecerse a esto:

docker swarm join --token SWMTKN-1-2j6qifl5jbb7zmcbr1ti7xl3qthmhj87b853afjmh29i7f6voi-5az2apq6vq80sls2uvd1sjz1o --advertise-addr 192.168.1.151 192.168.1.150:2377

Esta máquina es ahora una máquina worker del swarm.

En la máquina máster (192.168.1.150), crea un nuevo archivo docker-compose.yml con el siguiente contenido:

version: '3'

services:
  discovery-server:
    image: alejandrodu/microservices-discovery-server
    ports:
      - "8001:8080"
    command: --spring.cloud.inetutils.preferredNetworks=10.0 --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  config-server:
    image: alejandrodu/microservices-config-server
    ports:
      - "8101:8080"
    command: --spring.cloud.inetutils.preferredNetworks=10.0 --spring.cloud.config.server.git.default-label=docker --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  biz-application:
    image: alejandrodu/microservices-biz-application
    ports:
      - "9001:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    volumes:
      - ~/h2-databases:/root/h2-databases
    deploy:
      resources:
        limits:
          memory: 128M

  admin-application:
    image: alejandrodu/microservices-admin-application
    ports:
      - "9101:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 256M

  news-application:
    image: alejandrodu/microservices-news-application
    ports:
      - "9201:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  website-application:
    image: alejandrodu/microservices-website-application
    ports:
      - "9301:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  proxy-server:
    image: alejandrodu/microservices-proxy-server
    ports:
      - "8080:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  monitor-application:
    image: alejandrodu/microservices-monitor-application
    ports:
      - "8201:8201"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

Lo principal a tener en cuenta en la configuración anterior es el uso de una preferred network al ejecutar un servicio, el volumen compartido en la biz-application y la rama de Git utilizada por el config-server.

Ejecuta el stack con el siguiente comando:

docker stack up -c docker-compose.yml microservices-demo

¿Qué sigue?
#

El propósito de este artículo no es explicar todos los conceptos y detalles sobre Docker y Docker Swarm, sino más bien darte algunas pautas sobre cómo experimentar y aprender por ti mismo.

Desde aquí puedes experimentar con proveedores de servicios en la nube, varios de los cuales facilitan los despliegues basados en Docker, replicando los servicios de descubrimiento de servicios y configuración para evitar que sean puntos únicos de fallo; y configurar un clúster de bases de datos por la misma razón.

Relacionados

Cómo llamar a un método Java desde una función JavaScript en el navegador
·132 palabras·1 min
Programación Vaadin
En este video demuestro cómo llamar a un método Java que se ejecuta en el servidor desde una función JavaScript que se ejecuta en el navegador web:
Desarrollo basado en copiar y pegar
·471 palabras·3 mins
Programación
Esta es la historia de un tal Sr. W. J.
Acoplamiento semántico
·477 palabras·3 mins
Programación
Code Complete es uno de esos libros que todo desarrollador debería leer.