El diseño orientado a microservicios no surge de la nada, yo lo veo como una evolución en el proceso de creación de aplicaciones, que debe adaptarse a los tiempos y a la mejora continua de la propia tecnologia, aprendiendo de los problemas presentes en otras metodologías de desarrollo. Sin embargo la incorporación de este paradigma en un entorno empresarial no debe tomarse a la ligera, y se debe tener en cuenta que el intento por solventar las deficiencias actuales introduce un halo de complejidad, que hace absolutamente necesario la preparación tanto del equipo de desarrolladores como de equipo de operaciones (sistemas), fomentando el acercamiento hacia el paradigma DevOps.
En este post voy a resumir los 10 consejos que se indican en el libro Applications and microservices with Docker and Containers publicado por The New Stack. Quisiera dejar claro que no es una traducción literal, es un resumen de las ideas principales, con un toque de mi percepción personal.
Los 10 mandamientos de los microservicios, como lo publican en The New Stack, serían los siguientes:
- Separación de servicios con y sin estado
Es importante entender las restricciones que presentan los servicios que deben mantener el estado (stateful). Estos deberían existir en un contenedor separado y fácilmente accesible. Los servicios que no mantienen el estado (stateless) son más fáciles y rápidos de escalar.
- No compartir bibliotecas o SDKs
Trata este punto uno de mis principios favoritos: “Don’ t Repeat Yourself” (DRY). Un microservicios debe ser diseñando como una pieza de software única, y para hacer una cosa y sólo una. Debería ser considerado independiente de otros microservicios. Nada de compartir modelos, persistencia u otras librerías, que provocarán a la larga problemas de mantenimiento, escalabilidad y fallos en varios microservicios a la vez.
A mi parecer esto es un indicador de un pobre diseño y una incorrecta aplicación del DDD (Domain-Driven Design).
- Evitar afinidad con el host
Cada microservicios debería poder ejecutarse en cualquier host del clusters predefinido. Es más, el buen diseño de un servicio debería facilitar la ejecución del mismo en contenedores de diferentes proveedores, como por ejemplo openshift o AWS, en el contexto de servicios en la nube.
- Orientar a los servicios a una tarea
Cada servicio debería ser diseñado con una tarea en mente, y sólo una. De esta manera en cada contenedor debe ejecutarse un sólo proceso. El Principio de Responsabilidad Única (SRP) nos ayudará a cumplir con este mandamiento.
- Utilizar protocolos ligeros para la comunicación
¿Cómo deben comunicarse los microservicios entre si? La recomendación es usar protocolos ligeros, independientes de la plataforma. En este punto se debe tener en cuenta al tipo de comunicación, síncrona o asíncrona. Para la primera se vienen prefiriendo los servicios basados en REST, mientras que para el segundo tipo es una buena elección el uso de Advanced Message Queuing Protocol (AMQP).
- Diseñar un punto de entrada y de salida bien definidos
Si se considera un microservicios como una caja negra, del que puede hacer uso otros servicios, el usuario final e incluso desarrolladores, es obligatorio la definición de una API consistente y estable, donde se especifique tanto las respuestas correctas como los errores producidos. Entra en juego aquí la creación y mantenimiento de una documentación útil para el servicio.
- Implementar un mecanismo de registro automático y descubrimiento
Cuando un nuevo microservicios entra en juego, al escalar uno servicios existentes o al ofrecer sevicios nuevos, ¿cómo lo descubre un consumidor de dichos servicios? Se hace necesario en estos casos un mecanismo de registro y/o descubrimiento que se encargue de gestionar el ciclo de vida de los microservicios.
- Comprobar explícitamente si hay reglas y restricciones
Este punto hace hincapié en la revisión de las restricciones y requisitos de cada microservicio a la hora de desplegarlo, como por ejemplo si hace uso de una caché compartida, el tipo de disco en el que se debe ejecutar, requisitos de CPU, memoria, etc.
- Preferencia de un sistema políglota
Una de las grandes ventajas del paradigma de desarrollo de microservicios es la posibilidad de elección de la mejor tecnología en cada momento. De esta manera es muy interesante poder optar por el lenguaje de programación que mejor resuelva el problema (polyglot programming) en incluso el mejor sistema de almacenamiento de información (polyglot persistence).
- Mantener revisiones de código y entornos de construcción del software independientes
Cada microservicio se implementa y mantiene por separado, independiente de los demás, siempre que respete la API se pueden desplegar nuevas versiones sin afectar al conjunto de la aplicación. Esto hace posible implementar el sistema de pruebas necesarios para cada servicio antes de pasar a producción.
A estos diez consejos yo añadiría un par más. El primero es que se hace absolutamente necesario un sistema de monitorización y análisis, para asegurar el óptimo rendimiento de la o las aplicaciones que hacen uso de los microservicios, el segundo, y para mi el más importante, es poder contar con un equipo humano con una actitud abierta y flexible, comprometido y dispuesto a aprender de los errores, a evolucionar y que comprenda el cliclo de vida de las soluciones demandadas actualmente.
Por supuesto que no hay que tomarse lo anteriormente descrito como la panacea y solución a todos los problemas. Se puede no estar de acuerdo con algunos puntos, incluso con todos. Espero comentarios y aportaciones.
Comentarios
Enhorabuena y muchas gracias!!