Hola Habr!
Estamos comenzando a traducir el libro
Microservices Patterns de Chris Richardson,
con ejemplos en Java . Ha pasado medio año antes del estreno en ruso, pero nos gustaría ofrecerle una especie de avance: una revisión ligeramente resumida de este libro de Ben Nadel, quien leyó la versión MEAP. La revisión cita activamente el texto de la versión Kindle de Richardson.

¡Bienvenido a cat!
Aprendí sobre Chris Richardson cuando
conocí su recurso en línea
Microservices.io . Donde, para ser honesto, hay una cantidad asombrosa de información, que decidí posponer para más adelante, porque en ese momento no sabía cómo abordarla, especialmente teniendo en cuenta que prácticamente no tenía ningún trato con los microservicios. Me gusta leer mas Por lo tanto, cuando supe que Chris estaba publicando el libro del autor
Microservicios Patrones: con ejemplos en Java , simplemente me sentí inspirado. Tanto que no podía esperar su salida. Así que adquirí y leí la "versión temprana" de Manning (MEAP). La semana pasada, acabo de hacer lo que estudié en este libro, y creo que este es un estudio fascinante, pragmático y holístico del enfoque de microservicios para el desarrollo.
Todo el libro está construido en la forma de la historia de Mary - CTO (CTO) de Food To Go, Inc (FTGO). La compañía busca hacer crecer el negocio lanzando la refactorización de su antigua aplicación monolítica y transformándola en una arquitectura de microservicio. Mary asume este proyecto, porque la velocidad de desarrollo ha disminuido, y los jefes están cada vez más molestos porque los programadores bajo el liderazgo de Mary no pueden producir nuevas características en una forma de bastante alta calidad.
Por supuesto, el principal problema de Mary es el llamado "infierno monolítico" en la terminología de Richardson. Si bien el monolito es una aplicación grande y en crecimiento, Richardson se enfoca en un aspecto bastante sutil de la migración FTGO, por lo que es más conveniente establecer y transmitir todos los conceptos. Al mismo tiempo, el contenido del libro es increíblemente digerible. La mayoría de las consideraciones de arquitectura suelen ser demasiado simplificadas o demasiado complicadas. Sin embargo, Richardson logró encontrar un punto medio mediante la construcción de un modelo de dominio que (casi) se ajusta a la cabeza, pero que al mismo tiempo es lo suficientemente complejo como para ilustrar interesantes flujos de tareas entre servicios en él.
Desde el principio, esperaba que Richardson fuera pragmático en cada detalle. Ningún aspecto del libro se presenta como una "bala de plata" o "la única solución". En todas partes vemos una elección calculada, un conjunto de compromisos claramente definidos. Por ejemplo, el autor incluso presenta la idea de microservicios en este sentido: siempre se debe evitar la arquitectura de microservicios, excepto en los casos en que sea absolutamente necesario:
Otro desafío asociado con el uso de la arquitectura de microservicios es decidir en qué punto del ciclo de vida de la aplicación comenzar a usar esta arquitectura. Al desarrollar la primera versión de una aplicación, a menudo aún no encuentra problemas que tal arquitectura resuelva. Además, el uso de una arquitectura distribuida bien equilibrada solo ralentizará el desarrollo. Tal dilema puede surgir en las startups, donde el desafío más importante generalmente radica en el rápido desarrollo de un modelo de negocio y su propia aplicación. Cuando se utiliza la arquitectura de microservicios, es mucho más difícil organizar iteraciones rápidas. El desarrollo de inicio definitivamente debe comenzar con una aplicación monolítica. (Versión Kindle, dirección 416)
Richardson también considera los microservicios en una perspectiva holística, discutiendo la dinámica del equipo como un círculo de problemas completamente independiente que se construye en la parte tecnológica. Por supuesto, considera temas como
la Ley de Conway y la "Maniobra inversa de
Conway ", pero al mismo tiempo, también aborda el hecho de que los programadores son personajes emocionales con quienes debes "vender" la idea de microservicios:
Pasando al paradigma del microservicio, se ve obligado a cambiar su arquitectura, su organización y sus procesos de desarrollo. Sin embargo, al final, el entorno de trabajo cambia, las condiciones en las que las personas trabajan y las personas, como ya se mencionó, son emocionales. Si se ignoran las emociones humanas, la introducción de microservicios en una organización puede convertirse en una ruta empinada. (Versión Kindle, dirección 718)
Las estrategias descritas por el autor conciernen a todo el negocio, afectan a los gerentes y ejecutivos que pueden no atreverse a comenzar una refactorización grande, tomando valiosos recursos de ella, personas que podrían desarrollar activamente nuevas características:
Un beneficio significativo de la refactorización paso a paso hacia la arquitectura de microservicios es que dicha estrategia comienza a dar resultados de inmediato. Esta no es la situación cuando se "revisa" un código que no aporta ningún beneficio hasta que se complete por completo ...
Otra ventaja de la situación en la que el valor de la transición se adquiere en una etapa temprana es que podemos atraer apoyo empresarial para garantizar la migración. Tal soporte continuo es crucial, ya que cuanto más activa sea la refactorización, menos tiempo podrá dedicar al desarrollo de funciones. En algunas organizaciones, es difícil deshacerse de la deuda técnica, ya que los intentos anteriores podrían resultar demasiado ambiciosos y no brindar los beneficios deseados. Como resultado, el negocio es reacio a continuar invirtiendo en "limpieza". La naturaleza paso a paso de la refactorización en el caso de los microservicios significa que un equipo puede mostrar resultados valiosos muy a menudo. (Dirección de la versión de Kindle 10769)
Desde un punto de vista tecnológico, en el libro "Microservicios. Desarrollo y refactorización de patrones ”examinó una amplia gama de temas: desde arquitecturas hexagonales, pruebas e integración continua hasta patrones de mensajes y la creación de sistemas observables. Dicha cobertura implica que algunos temas del libro están cubiertos con más detalle que otros. Sin embargo, nuevamente, Richardson se las arregla perfectamente para equilibrar todo y dar tantos detalles para que uno pueda discutir razonablemente el tema sin desanimar al lector.
De hecho, los contenidos del libro están organizados de tal manera que usted mismo puede elegir en qué temas profundizar. En cada capítulo, antes de una inmersión detallada en el tema, se proporciona una lista de TL; DR, que enumera brevemente todos los pros y los contras. Por lo tanto, logra captar los puntos más importantes del capítulo sin leer cada palabra.
Honestamente, solo hojeé dos capítulos sobre la prueba de microservicios y un capítulo sobre la implementación de microservicios. Estoy seguro de que el autor resolvió estos temas a la perfección, pero me pareció que simplemente había más información de la que podía digerir. El despliegue no es una tarea diaria urgente para mí. Escribió varias pruebas en su vida.
Por lo tanto, quería dejar suficiente espacio en mi conciencia de cueva poco clara para poner allí material de todos los otros capítulos: sobre diseño orientado a temas (DDD), comunicación entre procesos y sincronización de datos.
Una de las secciones que me impresionó especialmente dice qué servicio debe manejar las solicitudes de un tipo especializado, a saber: encontrar restaurantes adecuados cerca de la ubicación actual del usuario:
Sin embargo, puede ser difícil implementar incluso aquellas solicitudes que son locales en términos de un servicio en particular. Esto es posible por varias razones. En primer lugar, porque (como se describe a continuación), a veces no es razonable implementar una solicitud en el servicio que posee los datos. Otra razón es que a veces la base de datos del servicio (o modelo de datos) no puede admitir eficientemente la solicitud (versión Kindle, dirección 5659)
... Si en la aplicación FTGO la información sobre restaurantes se almacena en [alguna otra] base de datos, la implementación de la consulta findAvailableRestaurant()
es mucho más complicada. Una réplica de los datos del restaurante debe almacenarse en un formulario que admita consultas geoespaciales. Por ejemplo, una aplicación podría usar la Biblioteca de indexación geoespacial para DynamoDB, donde la tabla se usa como índice geoespacial. Alternativa: la aplicación puede almacenar una réplica de los datos del restaurante en un tipo de base de datos completamente diferente. Una situación similar ocurre cuando usamos consultas de texto con una base de datos para la búsqueda de texto. (Versión Kindle, dirección 5675)
... En este caso, es aconsejable (al menos a primera vista) que la operación de solicitud sea implementada por el servicio que posee los datos. Sin embargo, además de la propiedad de los datos, se deben considerar otros factores.
También es necesario tener en cuenta la necesidad de separar las tareas y evitar sobrecargar los servicios con demasiadas funciones. Por ejemplo, la responsabilidad principal del equipo que desarrolla el servicio de restaurante es ayudar a los gerentes de restaurantes a servir el trabajo del establecimiento. Esta tarea no es en absoluto el plan de implementación de una solicitud crítica para trabajar con grandes cantidades de datos. Además, si el equipo de desarrollo fuera responsable de la operación findAvailableRestaurants()
, tendría miedo constantemente de introducir cambios que pudieran evitar que los consumidores realicen pedidos. (Versión Kindle, dirección 5675)
Aquí, mi cerebro explotó un poco porque vi por primera vez un servicio cuya única función era optimizar los datos de otro servicio para realizar una tarea específica. Sin embargo, como señala Richardson, esto es solo una abstracción más generalizada de la idea que subyace en la búsqueda de texto completo, por ejemplo, en Apache Lucene (esta herramienta proporciona indexación de texto completo sobre otro almacén de datos).
Sospecho, o más bien, deseo esperar, que, habiendo visto tal división de responsabilidades, el lector comenzará a trazar una nueva línea entre los servicios. Pensará no solo en la “propiedad de los datos”, sino que también comenzará a tener en cuenta las “oportunidades comerciales”, es decir, un factor de valor real para que la base de datos no parezca ser solo el lugar donde se almacena el estado.
Otro aspecto destacado en esta discusión es la importancia absoluta de la sincronización y replicación de datos, así como la mensajería asincrónica en una arquitectura de microservicio. Este tema recorre todo el libro de Richardson con un hilo rojo, sin importar de qué hablen: la creación de un microservicio desde cero o la refactorización gradual de un monolito en microservicios (un capítulo separado está dedicado a este tema). Él deja muy claro que la sincronización es esa fuerza principal que realmente permite que se realicen muchas cosas.
Podría mencionar muchas cosas interesantes. ¿Qué vale, por ejemplo, el hecho de que Richardson habla correctamente sobre la autenticación y la autorización en un sistema distribuido? Creo que este tema aún no se ha explorado completamente, por decirlo suavemente. El autor explica el diseño orientado a temas de la manera más accesible. También demuestra que incluso las clases muy simples pueden tener comportamiento.
Durante más de un año, he estado tratando de comprender adecuadamente la arquitectura de los sistemas distribuidos y los patrones de microservicio (lo cual es especialmente difícil, ya que mi trabajo diario está relacionado con el mantenimiento del monolito). Muchos de los textos que leí sobre estos temas son excesivamente superficiales o demasiado estrechos y al mismo tiempo en profundidad. El libro "Microservicios. Desarrollo y refactorización de patrones ”es, de hecho, el punto medio entre estos dos extremos.
Recomiendo encarecidamente este libro a todos (nuestros audaces) que intentan (incluso, hasta ahora sin éxito) cambiar de una arquitectura monolítica a un sistema distribuido.