Patrón: Arquitectura de microservicio
Contexto
Está desarrollando una aplicación empresarial del lado del servidor. Debe admitir una variedad de clientes diferentes, incluidos navegadores de escritorio, navegadores móviles y aplicaciones móviles nativas.La aplicación también puede exponer una API para que la consuman terceros.También puede integrarse con otras aplicaciones a través de servicios web o un intermediario de mensajes.La aplicación maneja solicitudes (solicitudes y mensajes HTTP) mediante la ejecución de la lógica empresarial; acceder a una base de datos; intercambiar mensajes con otros sistemas; y devolviendo una respuesta HTML / JSON / XML. Hay componentes lógicos correspondientes a diferentes áreas funcionales de la aplicación.
Problema
¿Cuál es la arquitectura de implementación de la aplicación?
Fuerzas
- Hay un equipo de desarrolladores trabajando en la aplicación
- Los nuevos miembros del equipo deben volverse productivos rápidamente
- La aplicación debe ser fácil de entender y modificar
- Quiere practicar la implementación continua de la aplicación
- Debe ejecutar varias instancias de la aplicación en varias máquinas para satisfacer los requisitos de escalabilidad y disponibilidad
- Quiere aprovechar las tecnologías emergentes (frameworks, lenguajes de programación, etc.)
Solución
Defina una arquitectura que estructura la aplicación como un conjunto de Servicios de colaboración. Este enfoque corresponde al eje Y del Scale Cube. Cada servicio es:
- Altamente mantenible y comprobable – permite ra pid y desarrollo e implementación frecuentes
- Vagamente acoplado con otros servicios: permite que un equipo trabaje de forma independiente la mayor parte del tiempo en sus servicios sin verse afectado por cambios en otros servicios y sin afectar otros servicios
- Implementable de forma independiente: permite a un equipo implementar su servicio sin tener que coordinarse con otros equipos
- Capaz de ser desarrollado por un equipo pequeño: esencial para una alta productividad al evitar la alta comunicación del jefe equipos
Los servicios se comunican mediante protocolos síncronos como HTTP / REST o protocolos asincrónicos como AMQP. Los servicios se pueden desarrollar e implementar de forma independiente. Cada servicio tiene su propia base de datos para desacoplarse de otros servicios. La coherencia de datos entre los servicios se mantiene utilizando el patrón Saga
Para obtener más información sobre la naturaleza de un servicio, lea este artículo.
Ejemplos
Aplicaciones de comercio electrónico ficticias en
Imaginemos que está creando una aplicación de comercio electrónico que toma pedidos de los clientes, verifica el inventario y el crédito disponible y los envía. La aplicación consta de varios componentes, incluido StoreFrontUI, que implementa la interfaz de usuario , junto con algunos servicios de backend para verificar el crédito, mantener el inventario y enviar pedidos. La aplicación consta de un conjunto de servicios.
Muéstrame el código
Por favor, mira las aplicaciones de ejemplo desarrolladas por Chris Richardson. Estos ejemplos en Github ilustran varios aspectos de la arquitectura de microservicios.
Contexto resultante
Beneficios
Esta solución tiene una serie de beneficios:
- Permite la entrega e implementación continuas de aplicaciones grandes y complejas.
- Mejor capacidad de mantenimiento: cada servicio es relativamente pequeño y, por lo tanto, más fácil de entender y cambiar
- Mejor capacidad de prueba: los servicios son más pequeños y más rápidos de probar
- Mejor implementación: servicios se puede implementar de forma independiente
- Le permite organizar el esfuerzo de desarrollo en torno a varios equipos autónomos. Cada equipo (las llamadas dos pizzas) posee y es responsable de uno o más servicios. Cada equipo puede desarrollar, probar, implementar y escalar sus servicios independientemente de todos los demás equipos.
- Cada microservicio es relativamente pequeño:
- Más fácil para un que el desarrollador entienda
- El IDE es más rápido, lo que hace que los desarrolladores sean más productivos
- La aplicación se inicia más rápido, lo que hace que los desarrolladores sean más productivos y acelera las implementaciones
- Aislamiento de fallas mejorado. Por ejemplo, si hay una pérdida de memoria en un servicio, solo ese servicio se verá afectado. Los otros servicios continuarán manejando solicitudes. En comparación, un componente que se comporte mal de una arquitectura monolítica puede derribar todo el sistema.
- Elimina cualquier compromiso a largo plazo con una pila de tecnología. Al desarrollar un nuevo servicio, puede elegir una nueva pila de tecnología. Del mismo modo, al realizar cambios importantes en un servicio existente, puede reescribirlo utilizando una nueva pila de tecnología.
Inconvenientes
Esta solución tiene varios inconvenientes:
- Los desarrolladores deben lidiar con la complejidad adicional de crear un sistema distribuido:
- Los desarrolladores deben implementar el mecanismo de comunicación entre servicios y lidiar con fallas parciales
- Implementar solicitudes que abarcan múltiples servicios es más difícil
- Probar las interacciones entre servicios es más difícil
- La implementación de solicitudes que abarcan múltiples servicios requiere una coordinación cuidadosa entre los equipos
- Las herramientas de desarrollador / IDE están orientadas a la construcción de aplicaciones monolíticas y no brindan soporte explícito para el desarrollo de aplicaciones distribuidas.
- Complejidad de implementación. En producción, también existe la complejidad operativa de implementar y administrar un sistema compuesto por muchos servicios diferentes.
- Mayor consumo de memoria. La arquitectura de microservicio reemplaza N instancias de aplicaciones monolíticas con instancias de servicios NxM. Si cada servicio se ejecuta en su propia JVM (o equivalente), lo que normalmente es necesario para aislar las instancias, entonces existe la sobrecarga de M veces más tiempos de ejecución de JVM. Además, si cada servicio se ejecuta en su propia VM (por ejemplo, instancia EC2), como es el caso de Netflix, la sobrecarga es aún mayor.
Problemas
Hay muchos problemas que debe abordar.
¿Cuándo usar la arquitectura de microservicio?
Un desafío al usar este enfoque es decidir cuándo tiene sentido usarlo. Al desarrollar la primera versión de Una aplicación, a menudo no tiene los problemas que resuelve este enfoque. Además, el uso de una arquitectura distribuida y elaborada ralentizará el desarrollo. Esto puede ser un problema importante para las startups cuyo mayor desafío es a menudo cómo evolucionar rápidamente el modelo de negocio y El uso de divisiones del eje Y puede hacer que sea mucho más difícil iterar rápidamente. Sin embargo, más adelante, cuando el desafío es cómo escalar y necesita usar la descomposición funcional, las dependencias enredadas pueden dificultar la descomposición de su aplicación monolítica en un conjunto de servicios.
Cómo descomponer la aplicación en servicios?
Otro desafío es decidir cómo dividir el sistema en microservicios. Esto es en gran medida un arte, pero hay una serie de estrategias que pueden ayudar:
- Descomponer por capacidad comercial y definir servicios correspondientes a capacidades comerciales.
- Descomponer por subdominio de diseño impulsado por dominio.
- Descomponer por verbo o caso de uso y definir servicios que son responsables de acciones particulares . p.ej. un
Shipping Service
que es responsable de enviar pedidos completos. - Descomponer por sustantivos o recursos definiendo un servicio que es responsable de todas las operaciones en entidades / recursos de un determinado escribe. p.ej. un
Account Service
que es responsable de administrar las cuentas de los usuarios.
Idealmente, cada servicio debe tener solo un pequeño conjunto de responsabilidades. (Tío) Bob Martin habla sobre el diseño de clases utilizando el Principio de Responsabilidad Única (SRP). El SRP define la responsabilidad de una clase como una razón para cambiar, y establece que una clase solo debe tener una razón para cambiar. Tiene sentido aplicar el SRP al diseño de servicios. también.
Otra analogía que ayuda con el diseño de servicios es el diseño de utilidades de Unix. Unix proporciona una gran cantidad de utilidades como grep, cat y find. Cada utilidad hace exactamente una cosa, a menudo excepcionalmente bien, y está destinado a ser combinado con otras utilidades usando un script de shell para realizar tareas complejas.
¿Cómo mantener la consistencia de los datos?
Para asegurar un acoplamiento flexible, cada servicio tiene su propio Mantener la coherencia de los datos entre los servicios es un desafío porque las transacciones distribuidas / de compromiso de 2 fases no una opción para muchas aplicaciones.Una aplicación debe usar en su lugar el patrón Saga.Un servicio publica un evento cuando sus datos cambian.Otros servicios consumen ese evento y actualizan sus datos.Existen varias formas de actualizar datos y publicar eventos de manera confiable, incluyendo Event Sourcing y Seguimiento del registro de transacciones.
¿Cómo implementar consultas?
Otro desafío es implementar consultas que necesitan recuperar datos propiedad de múltiples servicios.
- La API Patrones de composición y segregación de responsabilidad de consultas de comandos (CQRS).
Hay muchos patrones relacionados con el patrón de microservicios. La arquitectura monolítica es una alternativa a la arquitectura de microservicio. Los otros patrones abordan los problemas que encontrará al aplicar la arquitectura de microservicio.
- Patrones de descomposición
- Descomponer por capacidad comercial
- Descomponer por subdominio
- El patrón de base de datos por servicio describe cómo El servicio tiene su propia base de datos para garantizar un acoplamiento flexible.
- El patrón API Gateway define cómo los clientes acceden a los servicios en una arquitectura de microservicio.
- Los patrones de descubrimiento del lado del cliente y descubrimiento del lado del servidor se utilizan para enrutar las solicitudes de un cliente a un instancia de servicio disponible en una arquitectura de microservicio.
- Los patrones de invocación de procedimiento remoto y de mensajería son dos formas diferentes en que los servicios pueden comunicarse.
- Los patrones de servicio único por host y servicios múltiples por host son dos estrategias de implementación diferentes.
- Patrones de preocupaciones transversales: patrón de chasis de microservicio y configuración externa
- Patrones de prueba: prueba de componente de servicio y prueba de contrato de integración de servicio
- Circuito Breaker
- Token de acceso
- Patrones de observabilidad:
- Agregación de registros
- Métricas de la aplicación
- Registro de auditoría
- Seguimiento distribuido
- Seguimiento de excepciones
- API de verificación de estado
- Registre implementaciones y cambios
- Patrones de IU:
- Composición de fragmentos de página del lado del servidor
- Composición de la IU del lado del cliente
Usos conocidos
La mayoría de los sitios web a gran escala, incluidos Netflix, Amazona y eBay, han evolucionado de una arquitectura monolítica a una arquitectura de microservicio.
Netflix, que es un servicio de transmisión de video muy popular que es responsable para hasta el 30% del tráfico de Internet, tiene una arquitectura orientada a servicios a gran escala. Manejan más de mil millones de llamadas por día a su API de transmisión de video desde más de 800 tipos diferentes de dispositivos. Cada llamada de API se expande a un promedio de seis llamadas a servicios de backend.
Amazon.com originalmente tenía una arquitectura de dos niveles. Para escalar, migraron a una arquitectura orientada a servicios que consta de cientos de servicios de backend. Varias aplicaciones llaman a estos servicios, incluidas las aplicaciones que implementan el sitio web de Amazon.com y la API de servicios web. La aplicación del sitio web de Amazon.com llama a 100-150 servicios para obtener el datos que solían construir una página web.
El sitio de subastas ebay.com también evolucionó de una arquitectura monolítica a una arquitectura orientada a servicios. El nivel de aplicación consta de múltiples aplicaciones independientes. Cada aplicación implementa la lógica empresarial para un área de función específica, como comprar o vender. Cada aplicación utiliza divisiones del eje X y algunas aplicaciones, como la búsqueda, utilizan divisiones del eje Z. eBay.com también aplica una combinación de escalado de estilo X, Y y Z a la nivel de base de datos.
Hay muchos otros ejemplos de empresas que utilizan la arquitectura de microservicios.
Chris Richardson tiene ejemplos de aplicaciones basadas en microservicios.
Consulte también
Vea mi discurso de apertura de Code Freeze 2018, que proporciona una buena introducción a la arquitectura de microservicios.