En resumen, el estilo arquitectónico de microservicio es un enfoque para desarrollar una sola aplicación como un conjunto de pequeños servicios, cada uno ejecutándose en su propio proceso y comunicándose con mecanismos ligeros, a menudo una API de recursos HTTP.
Si bien un programa *nix o un microservicio pueden ser muy limitados o ni siquiera muy interesantes por sí solos, es la combinación de estas unidades que funcionan de forma independiente lo que revela su verdadero beneficio y, por lo tanto, su poder.
| *nix | Microservicios |
Unidad de ejecución | programa usando stdin /salida estándar | servicio con API HTTP o gRPC |
Flujo de datos | Tubos | ? |
Configuración y parametrización | Argumentos de la línea de comandos,
variables de entorno, archivos de configuración | Documentos JSON/YAML |
Descubrimiento | Administrador de paquetes, hombre, hacer | DNS, variables de entorno, OpenAPI |
Exploremos cada línea con un poco más de detalle.
Unidad de ejecución
Más sobre microservicios
- Hoja de trucos de microservicios
- Cómo explicar los microservicios a su CEO
- Libro electrónico gratuito:Microservicios frente a arquitectura orientada a servicios
- Curso en línea gratuito:desarrollo de aplicaciones nativas de la nube con arquitecturas de microservicios
- Últimos artículos sobre microservicios
La unidad de ejecución en *nix (como Linux) es un archivo ejecutable (script binario o interpretado) que, idealmente, lee la entrada de stdin y escribe la salida en stdout . Una configuración de microservicios se ocupa de un servicio que expone una o más interfaces de comunicación, como las API HTTP o gRPC. En ambos casos, encontrará ejemplos sin estado (esencialmente un comportamiento puramente funcional) y ejemplos con estado, donde, además de la entrada, algún estado interno (persistente) decide qué sucede.
Flujo de datos
Tradicionalmente, los programas *nix podían comunicarse a través de conductos. En otras palabras, gracias a Doug McIlroy, no es necesario crear archivos temporales para distribuirlos y cada uno puede procesar flujos de datos prácticamente infinitos entre procesos. Que yo sepa, no hay nada comparable a una canalización estandarizada en microservicios, además de mi pequeño experimento basado en Apache Kafka de 2017.
Configuracion y parametrizacion
¿Cómo configura un programa o servicio, ya sea de forma permanente o por llamada? Bueno, con los programas *nix, básicamente tiene tres opciones:argumentos de línea de comandos, variables de entorno o archivos de configuración completos. En los microservicios, normalmente trabaja con documentos YAML (o peor aún, JSON), definiendo el diseño y la configuración de un solo microservicio, así como las dependencias y la configuración de comunicación, almacenamiento y tiempo de ejecución. Los ejemplos incluyen definiciones de recursos de Kubernetes, especificaciones de trabajo de Nomad o archivos de Docker Compose. Estos pueden o no estar parametrizados; es decir, tiene algún lenguaje de plantillas, como Helm en Kubernetes, o se encuentra haciendo una gran cantidad de sed -i comandos.
Descubrimiento
¿Cómo sabe qué programas o servicios están disponibles y cómo se supone que deben usarse? Bueno, en *nix, normalmente tienes un administrador de paquetes y un buen viejo; entre ellos, deberían poder responder a todas las preguntas que pueda tener. En una configuración de microservicios, hay un poco más de automatización para encontrar un servicio. Además de enfoques personalizados como SmartStack de Airbnb o Eureka de Netflix, generalmente existen enfoques basados en variables de entorno o basados en DNS que le permiten descubrir servicios de forma dinámica. Igualmente importante, OpenAPI proporciona un estándar de facto para la documentación y el diseño de API HTTP, y gRPC hace lo mismo para casos de alto rendimiento más estrechamente acoplados. Por último, pero no menos importante, tenga en cuenta la experiencia del desarrollador (DX), comenzando por escribir buenos Makefiles y terminando por escribir sus documentos con (¿o en?) estilo. .
Pros y contras
Tanto *nix como los microservicios ofrecen una serie de desafíos y oportunidades
Composibilidad
Es difícil diseñar algo que tenga un enfoque claro y nítido y que también pueda funcionar bien con otros. Es aún más difícil hacerlo bien en diferentes versiones e introducir las respectivas capacidades de manejo de casos de error. En los microservicios, esto podría significar una lógica de reintento y tiempos de espera. ¿Tal vez sea una mejor opción subcontratar estas funciones en una red de servicios? Es difícil, pero si lo haces bien, su reutilización puede ser enorme.
Observabilidad
En un monolito (en 2018) o un gran programa que intenta hacerlo todo (en 1984), es bastante sencillo encontrar al culpable cuando las cosas van mal. Pero, en un
yes | tr \\n x | head -c 450m | grep n
o una ruta de solicitud en una configuración de microservicios que involucra, digamos, 20 servicios, ¿cómo comenzar? para saber cuál se está portando mal? Afortunadamente, tenemos estándares, en particular OpenCensus y OpenTracing. La observabilidad aún podría ser el mayor bloqueador individual si está buscando pasar a los microservicios.
Estado global
Si bien puede que no sea un problema tan grande para los programas * nix, en los microservicios, el estado global sigue siendo un tema de discusión. Es decir, cómo asegurarse de que el estado local (persistente) se gestione de manera eficaz y cómo hacer que el estado global sea coherente con el menor esfuerzo posible.
Resumiendo
Al final, la pregunta sigue siendo:¿Está utilizando la herramienta adecuada para una tarea determinada? Es decir, de la misma manera que un programa *nix especializado que implementa una variedad de funciones podría ser la mejor opción para ciertos casos de uso o fases, podría ser que un monolito sea la mejor opción para su organización o carga de trabajo. Independientemente, espero que este artículo lo ayude a ver los muchos y sólidos paralelismos entre la filosofía de Unix y los microservicios; tal vez podamos aprender algo de la primera para beneficiar a la segunda.