Aug 27

¿Por qué Microservicios?

Monolítico vs MicroserviciosHe leído este artículo ¿Por qué Microservicios? y ahí van mis opiniones.

Un resumen del artículo

Si ya te lo has leído, te puedes saltar este apartado, pero por si te da pereza leerlo entero en inglés, comenta que las pegas de una arquitectura tradicional monolítica y basada en capas son:

  1. En una arquitectura monolítica cada desarrollador tiene que "cargar" con todo el código de todo el mundo, no sólo con la parte en la que está especializado. Extraer del control de versiones, compilar completo, desplegar al completo, etc, etc.
  2. Los distintos módulos dependen mucho unos de otros. Un pequeño cambio en uno puede afectar a varios módulos distintos.
  3. En una arquitectura en capas (por ejemplo, interfaz de usuario, capa de negocio y capa de persistencia), los desarrolladores suelen especializarse en una de las capas, Cuando hay algún problema, por no esperar por los desarrolladores de la otra capa, el desarrollador mete en su capa cosas que no deberían serlo. Por ejemplo, accesos directos a base de datos desde la interfaz de usuario.
  4. El equipo de soporte no suele ser el mismo que el de desarrollo, por lo que durante el mantenimiento del software, el equipo de soporte  puede requerir la ayuda del equipo de desarrollo.
  5. En una arquitectura de capas, los desarrolladores de cada capa suelen especializarse en su capa y desconocen las otras. Cuando hay errores en el código, suele haber problemas para saber exactamente en qué capa está el problema y suele ser necesaria la colaboración de los desarrolladores de todas las capas para localizarlo y corregirlo.

A continuación el artículo enumera las ventajas e inconvenientes de una arquitectura basada en microservicios. Cada microservicio es un desarrollo independiente de los demás microservicios, llevado por uno o más desarrolladores que sólo se preocupan de su microservicio. Las ventajas que enumera son

  1. Cada microservicio es independiente de los demás, así que puede desarrollarse en su propio lenguaje de programación. En una arquitectura monolítica, todo debe estar desarrollado en el mismo lenguaje.
  2. El microservicio suele ser pequeño, por lo que el desarrollador se centra en él y lo conoce muy bien.
  3. Los microservicios hablan entre sí por algún protocolo sencillo y "tonto", como REST. Al contrario que en una arquitectura SOA donde los servicios hablan a través de un ESB, que suele tener demasiada inteligencia.
  4. Cada microservicio puede tener su propia base de datos, por lo que incluso uno puede tener una base de datos SQL, otro una base de datos NoSQL, etc.

Y por supuesto, también menciona algunas pegas, que resumidas vienen a ser que el conjunto es más difícil de depurar (es difícil seguir con un debugger las llamadas entre microservicios distintos), no hay un log centralizado y las llamadas entre servicios vía REST suelen ser más lentas que las llamadas internas dentro de una arquitectura monolítica.

mis opiniones

Aunque el artículo está bien y cuenta cosas interesantes, no veo muy claros algunos razonamientos que hace.

En una arquitectura monolítica se puede hacer, además de capas, módulos independientes y separados, con interfaces claras para comunicarse entre ellos. Si cada uno de estos módulos contiene todas las capas y se organiza como un proyecto separado, tenemos parte de las ventajas de los microservicios sin necesidad de microservicios:: Un desarrollador no tiene que cargar con el código de todo el mundo (salvo para el despliegue de su módulo en la aplicación completa), cada desarrollador conocería todas las capas de su módulo, que sería más  pequeño que la aplicación completa, fácil de depurar.  Ahora, siempre es cierto que una cosa son las intenciones (hacer el módulo aislado con una interfaz clara) y otra es la realidad (los desarrolladores usan los módulos de otros saltándose esa interfaz, simplemente porque tienen las clases a mano aunque sea como librería. Esto es más difícil con microservicios.

Lo de que los módulos dependen unos de otros y un pequeño cambio afecta a varios, me suena más a problema de diseño que a problema de la arquitectura en sí. Si cada módulo tiene una interfaz clara definida, no debería haber problemas si cambias el módulo mientras no cambies la interfaz. Lo mismo pasaría con los microservicios si decides cambiar la interfaz REST que ofrecen, afectará a otros módulos.

Lo de que el equipo de soporte no suele ser el mismo que el de desarrollo …. bueno, creo que no tiene nada que ver con la arquitectura que se use. Hay el mismo problema si unos desarrolladores desarrollan los microservicios y luego son otros los que los mantienen.

Que un problema en una arquitectura en capas involucre simultánemente a desarrolladores de cada capa … lo cambiamos porque un problema en una arquitectura en microservicios involucre simultáneamente a desarrolladores de cada microservicio involucrado.

Y en cuanto a las ventajas, bien, cada microservicio se puede desplegar y testear por separado. Eso es una ventaja importante, pero relativamente cierta, ya que ese microservicio puede tener que llamar a otros que también necesitarían ser desplagados y desplegar a su vez los que estos últimos necesiten). Es cierto que se pueden usar lenguajes y bases de datos distintas para cada microservicio, pero esta ventaja es "cuestionable". ¿Se te ocurre algún tipo de aplicación en el que haya partes que sea claramente mejor desarrollarlas en un lenguaje y otras en otro y que haya partes para las que claramente sea mejor una base de datos y para otras partes otra. Posiblemente, a poco que pienses, sí se te ocurre, pero … ¿es una aplicación más o menos estándar de las que se suelen pedir algún cliente?. En cuanto a bases de datos distintas, también se puede hacer así en un sistema monolítico, cada módulo que se desarrolle podría tener su propia base de datos.

Hay sin embargo otras ventajas que tienen los microservicios que no menciona el artículo

La principal, desde mi punto de vista, es que la aplicación es fácilmente "clusterizable". Un desarrollo monolítico corre en  un sólo servidor. Los microservicios podemos ejecutarlos cada uno en un servidor distinto si es necesario.

Otra ya la he mencionado, si un microservicio se desarrolla por separado de los demás y no se meten en el proyecto dependencias del código de otros microservicios, es imposible saltarse las fronteras. Con módulos bien definidos, como al final un módulo depende de la interfaz de otro, también ve sus clases internas (hablo de java, donde si ves un jar, ves todas sus clases), por lo que un desarrollador por descuido o por las prisas, puede saltarse la frontera.

Y una última ventaja, es la reusabilidad. Un microservicio podemos usarlo tal cual posiblemente en otro proyecto, siempre que nos valga tal cual, simplemente con arrancarlo. Con módulos podemos también reusarlos, pero tienen que estar pensados para eso, ya que pueden necesitar configuraciones distintas en otro proyecto, como acceder a otra base de datos, Por supuesto, esto es relativamente cierto, ya que tanto un microservicio como un módulo puede necesitar para funcionar otros microservicios u otros módulos, que también debemos traernos.

resumiendo

Como ventajas de los microservicios veo principalmente cosas como el arranque distribuido en varios servidores o la reutilización en la práctica es más fácil que la de un módulo de una aplicación monolítica.

No me parece que soluciones los problemas de desarrollo tradicionales al hacer software, que creo que son más generales al software que específicos de la arquitectura. Si los módulos tienen una dependencia fuerte más allá de la interfaz, es que están mal diseñados/desarrollados. Si los desarrolladores se especializan en capas, deberían especializarse en módulos y en todas las capas de su módulo. Si cuando los desarrolladores se especializan en un tema hay problemas para resolver los bug, porque nunca se sabe en qué parte está, es común tanto si hablamos de capas, como si hablamos de microservicios que colaboran (¿en qué microservicio está el problema?), como si hablamos de módulos que colaboran.