Diseño de arquitectura de microservicios

Azure DevOps

Los microservicios constituyen un estilo arquitectónico popular para la compilación de aplicaciones resistentes, altamente escalables, que se pueden implementar de forma independiente y que evolucionan rápidamente. Pero una arquitectura de microservicios correcta requiere un enfoque diferente para diseñar y compilar aplicaciones.

Una arquitectura de microservicios consta de una colección de servicios autónomos y pequeños. Cada uno de servicio es independiente y debe implementar una funcionalidad de negocio individual dentro de un contexto delimitado. Un contexto delimitado es una división natural de una empresa y proporciona un límite explícito dentro del cual existe un modelo de dominio.

Diagrama lógico del estilo de arquitectura de microservicios.

¿Qué son los microservicios?

  • Los microservicios son pequeños e independientes, y están acoplados de forma imprecisa. Un único equipo reducido de programadores puede escribir y mantener un servicio.

  • Cada servicio es un código base independiente, que puede administrarse por un equipo de desarrollo pequeño.

  • Los servicios pueden implementarse de manera independiente. Un equipo puede actualizar un servicio existente sin tener que volver a generar e implementar toda la aplicación.

  • Los servicios son los responsables de conservar sus propios datos o estado externo. Esto difiere del modelo tradicional, donde una capa de datos independiente controla la persistencia de los datos.

  • Los servicios se comunican entre sí mediante API bien definidas. Los detalles de la implementación interna de cada servicio se ocultan frente a otros servicios.

  • Admite la programación políglota. Por ejemplo, no es necesario que los servicios compartan la misma pila de tecnología, las bibliotecas o los marcos.

Además de los propios servicios, hay otros componentes que aparecen en una arquitectura típica de microservicios:

Administración e implementación. Este componente es el responsable de la colocación de servicios en los nodos, la identificación de errores, el reequilibrio de servicios entre nodos, etc. Normalmente, este componente es una tecnología estándar, como Kubernetes, en lugar de algo creado de forma personalizada.

Puerta de enlace de API La puerta de enlace de API es el punto de entrada para los clientes. En lugar de llamar a los servicios directamente, los clientes llaman a la puerta de enlace de API, que reenvía la llamada a los servicios apropiados en el back-end.

Entre las ventajas de usar una puerta de enlace de API se encuentran las siguientes:

  • Desacoplan los clientes de los servicios. Los servicios pueden cambiar de versión o refactorizarse sin necesidad de actualizar todos los clientes.

  • Los servicios pueden utilizar los protocolos de mensajería que no son fáciles de usar para un servicio web, como AMQP.

  • La puerta de enlace de API puede realizar otras funciones transversales como la autenticación, el registro, la terminación SSL y el equilibrio de carga.

  • Directivas estándar, como por ejemplo, para la limitación, el almacenamiento en caché, la transformación o la validación.

Ventajas

  • Agilidad. Dado que microservicios se implementan de forma independiente, resulta más fácil de administrar las correcciones de errores y las versiones de características. Puede actualizar un servicio sin volver a implementar toda la aplicación y revertir una actualización si algo va mal. En muchas aplicaciones tradicionales, un error en una parte de la aplicación puede bloquear todo el proceso de lanzamiento. Es posible que se requieran nuevas características a la espera de que se integre, pruebe y publique una corrección de errores.

  • Equipos pequeños y centrados. Un microservicio debe ser lo suficientemente pequeño como para que un solo equipo de características lo pueda compilar, probar e implementar. Los equipos pequeños favorecen la agilidad. Los equipos grandes suelen ser menos productivos, porque la comunicación es más lenta, aumenta la sobrecarga de administración y la agilidad disminuye.

  • Base de código pequeña. En las aplicaciones monolíticas, con el paso del tiempo se da la tendencia de que las dependencias del código se acaben enredando. Para agregar una característica nueva, es preciso modificar el código en muchos lugares. Al no compartir el código ni los almacenes de datos, la arquitectura de microservicios minimiza las dependencias y resulta más fácil agregar nuevas características.

  • Mezcla de tecnologías. Los equipos pueden elegir la tecnología que mejor se adapte al servicio de una combinación de pilas de tecnología, según corresponda.

  • Aislamiento de errores. Si un microservicio individual no está disponible, no interrumpirá toda la aplicación, siempre que los microservicios ascendentes estén diseñados para controlar los errores correctamente. Por ejemplo, puede implementar el patrón Circuit Breaker, o bien diseñar la solución para que los microservicios se comuniquen entre sí mediante patrones de mensajería asincrónica.

  • Escalabilidad. Los servicios se pueden escalar de forma independiente, lo que permite escalar horizontalmente los subsistemas que requieren más recursos, sin tener que escalar horizontalmente toda la aplicación. haciendo uso de un orquestador como Kubernetes, puede empaquetar una mayor densidad de servicios en un solo host, lo cual permite un uso más eficiente de los recursos.

  • Aislamiento de los datos. Al verse afectado solo un microservicio, es mucho más fácil realizar actualizaciones del esquema. En una aplicación monolítica, las actualizaciones del esquema pueden ser muy complicadas, ya que las distintas partes de la aplicación pueden tocar los mismos datos, por lo que realizar modificaciones en el esquema resulta peligroso.

Desafíos

Las ventajas de los microservicios tienen un "precio". Estos son algunos de los aspectos que deben tenerse en cuenta antes de embarcarse en una arquitectura de microservicios.

  • Complejidad. Una aplicación de microservicios tiene más partes en movimiento que la aplicación monolítica equivalente. Cada servicio es más sencillo, pero el sistema como un todo es más complejo.

  • Desarrollo y pruebas. La escritura de un servicio pequeño que utilice otros servicios dependientes requiere un enfoque que no sea escribir una aplicación tradicional monolítica o en capas. Las herramientas existentes no siempre están diseñadas para trabajar con dependencias de servicios. La refactorización en los límites del servicio puede resultar difícil. También supone un desafío probar las dependencias de los servicios, especialmente cuando la aplicación está evolucionando rápidamente.

  • Falta de gobernanza. El enfoque descentralizado para la generación de microservicios tiene ventajas, pero también puede causar problemas. Es posible que acabe con multitud de lenguajes y marcos de trabajo diferentes que dificulten el mantenimiento de la aplicación. Podría resultar útil establecer algunos estándares para todo el proyecto, sin restringir en exceso la flexibilidad de los equipos. Esto se aplica especialmente a las funcionalidades transversales, como el registro.

  • Congestión y latencia de red. El uso de muchos servicios pequeños y detallados puede dar lugar a más comunicación interservicios. Además, si la cadena de dependencias del servicio se hace demasiado larga (el servicio A llama a B, que llama a C...), la latencia adicional puede constituir un problema. Tendrá que diseñar las API con atención. Evite que las API se comuniquen demasiado, piense en formatos de serialización y busque lugares para utilizar patrones de comunicación asincrónica como la nivelación de carga basada en colas.

  • Integridad de datos. Cada microservicio es responsable de la conservación de sus propios datos. Como consecuencia, la coherencia de los datos entre varios servicios puede suponer un problema. Los distintos servicios conservan los datos a horas diferentes, mediante tecnología diferente y con niveles de éxito potencialmente diferentes. Cuando en la conservación de una fecha nueva o modificada participa más de un microservicio, es poco probable que el cambio de datos completo pueda considerarse una transacción ACID. En cambio, la técnica está más en línea con BASE (Basically Available, Soft state, and Eventually consistent). Adopte una coherencia final cuando sea posible.

  • Administración. Para tener éxito con los microservicios se necesita una cultura de DevOps consolidada. El registro correlacionado entre servicios puede resultar un desafío. Normalmente, el registro debe correlacionar varias llamadas de servicio para una sola operación de usuario.

  • Control de versiones. Las actualizaciones de un servicio no deben interrumpir servicios que dependen de él. Es posible que varios servicios se actualicen en cualquier momento; por lo tanto, sin un cuidadoso diseño, podrían surgir problemas con la compatibilidad con versiones anteriores o posteriores.

  • Serie de aptitudes. Los microservicios son sistemas muy distribuidos. Evalúe cuidadosamente si el equipo tiene los conocimientos y la experiencia para desenvolverse correctamente.

Proceso para crear una arquitectura de microservicios

Los artículos que se enumeran aquí presentan un enfoque estructurado para diseñar, crear y usar una arquitectura de microservicios.

Análisis de dominios. Para evitar algunas dificultades habituales al diseñar microservicios, use el análisis de dominios para definir los límites del microservicio. Siga estos pasos:

  1. Use el análisis de dominios para modelar microservicios.
  2. Use un diseño basado en dominios táctico para diseñar microservicios.
  3. Identifique los límites de los microservicios.

Diseño de los servicios. Los microservicios requieren un enfoque diferente para diseñar y compilar aplicaciones. Para más información, consulte Diseño de una arquitectura de microservicios.

Funcionamiento en producción. Como las arquitecturas de microservicios se distribuyen, debe tener operaciones sólidas para la implementación y supervisión.

Arquitecturas de referencia de microservicios para Azure