Sin lugar a dudas el año 2020 es uno que recordaremos por siempre y aparecerá en los libros de historia (y Wikipedia). Entre tanto caos, las formas de trabajo se vieron obligadas a cambiar, y empresas que antes rechazaban el trabajo desde casa tuvieron que adaptarse. De esta manera, equipos que antes compartían una misma sala y sufrían reuniones innecesarias, empezaron a funcionar como equipos distribuidos (sistemas distribuidos), que manejan una cola de mensajes vía Correo electrónico o Slack (comunicación asincrónica) y tienen reuniones con menos frecuencia (comunicación sincrónica).
Gran parte de la industria IT está de acuerdo con el trabajo remoto; y mas allá de cuestiones como si el empleador debe brindar el equipo de trabajo (monitores, sillas, notebook) y pagar internet; no hay otro tipo de quejas.
Si asumimos entonces que el equipo de trabajo distribuido es mejor, ¿podemos asumir que una empresa que usa microservicios es mejor? La respuesta tiene distintas aristas que hay que analizar.
En los próximos párrafos encontrarán lo bueno, lo malo y lo feo de los microservicios. Si querés adentrarte mas en el tema, te invito a ver estos dos live streams que hicimos en Stream 404:
Lo bueno, lo malo y lo feo
Título de película y también de retrospectiva: consiste en nombrar cosas buenas (que salieron bien y que el equipo debería repetir), cosas malas (que nunca deberían haber pasado y se deben evitar), y cosas feas (que no salieron bien y deberían mejorar para que sean hermosas).
Aplicado a microservicios podemos nombrar lo bueno de usarlos, lo malo como posibles problemas a evitar y lo feo como esas transiciones que un equipo tiene que atravesar.
Lo bueno
SOLID, un conjunto de principios que se aplican a la programación, establece el \”Single Responsibility Principle\” (SRP): Una clase, archivo, paquete (dependiendo del lenguaje de programación) debe tener una única razón de cambio. Los microservicios deben aprovechar el SRP para delimitar una función del sistema y encapsular la misma en el servicio en sí. De esta forma, detectar cierta funcionalidad se vuelve mas fácil.
El ciclo de vida de desarrollo es más corto. Siempre y cuando el alcance del microservicio esté bien delimitado, su desarrollo no debería tomar mas de dos semanas, lo cual lo hace fácilmente reemplazable en caso de que se requiera una implementación totalmente diferente.
Siguiendo la misma línea, un servicio que tiene un alcance acotado es mas fácil de testear; una buena base de test unitarios que garanticen que las reglas de negocio sean válidas es fundamental para asegurar el funcionamiento del sistema en sí.
Por último, en empresas más grandes, donde cada equipo representa una función, es común encontrar no más de 6 personas que estén específicamente trabajando en uno o dos servicios y tengan total libertad para desarrollarlos, siempre y cuando se cumplan los contratos que el servicio establezca con otros servicios de otros equipos.
Lo malo
Los hashtags. Suena ridículo, pero para atraer gente a las Start-Ups hay muchos equipos que se lanzan a hacer microservicios, sin siquiera considerar las ventajas y las desventajas, dado que los microservicios \”están de moda\”. El estigma de los monolitos es tal que incluso mencionarlos causa pánico. En una empresa nueva o en un proyecto nuevo, donde el negocio no esta muy definido y/o estable, la mejor alternativa es empezar con un monolito y luego migrar a microservicios.
También, hay un cambio de paradigma en cuanto a cómo testear el sistema. Muchos equipos basan todos sus test en un Automation E2E (end to end) que cubre todo el sistema: incluido Front y Back end. Si bien esto parece una buena idea, uno de los principios de los microservicios es que los deploy son independientes. Si tenemos que pasar a producción 10 servicios en simultáneo y cada vez que ejecutamos los E2E tardamos 5 minutos; tendríamos que esperar 50 minutos para tener todos los cambios en producción. Esto no es escalable en sistemas grandes y por eso se favorecen los test unitarios, para testear el negocio; y los test de integración, para estar seguros que podemos acceder a la base de datos, o ejecutar un llamado a otro servicio.
El tooling (librerías, soporte de infraestructura, entre otros) puede generar un problema en un equipo no tan maduro. La autonomía significa que el mismo puede elegir un lenguaje de programación que no tiene porque ser usado en otro servicio. Sin embargo, hay veces que un lenguaje ya establecido en la empresa tiene un tooling maduro, y elegir otro lenguaje no suele ser una opción razonable. Hay que pensar también que si una empresa maneja muchos lenguajes de programación necesita muchos empleados con diferentes skill sets lo cual puede llegar a ser una complicación en caso de que integrantes de un equipo se vayan de la empresa, o quieran cambiar a otro equipo. Si bien, en mi opinión, uno no sabe programar en un lenguaje y para cambiar a otro tiene que empezar desde \”trainee\”, siempre hay una curva de aprendizaje en la cual uno se tiene que familiarizar con la sintaxis, frameworks y bondades del mismo.
Lo feo
Los microservicios no son acordes para un negocio nuevo en el cual no haya expertos del dominio o cuando el dominio no sea estable. Esto, también mencionado en lo malo, es algo con lo que el equipo tiene que trabajar. Lo más acorde al principio es empezar con un monolito y cuando el dominio se estabilice, empezar a segmentar gradualmente partes que estén bien delimitadas y probar qué tan bien funciona la integración con el monolito. Al cabo de unos meses, o años, el monolito estará totalmente desacoplado en un sistema distribuido.
Todo tiene que ser observable y medible. En un monolito los puntos de error suelen ser más fáciles de detectar dado que todo es parte de la misma aplicación. Igualmente, la respuesta a si el sistema está caído no tiene grises. Es sí o no. En un sistema distribuido esto cambia. Cada microservicio debe tener sus métricas y alertas configuradas para saber si hubo un problema y si es necesario reducir (downgrade) la funcionalidad mientras esto suceda. Las redes fallan, y en microservicios no se trata de \”evitar que algo falle\” si no de alertar y responder cuando algo falle.
De comunicación sincrónica a comunicación asíncrona. Muchas operaciones no necesitan procesarse en \”batch\”. Esto es un cambio de paradigma muy grande. Si un cliente realiza una compra en un sistema no es necesario que se realice el pago y luego se procese el envío de un email con el recibo de una forma sincrónica. Para esto se implementa un patrón llamado \”Tell don\’t ask\” (contá, no preguntes), lo cual significa que el servicio va a informar un evento de la índole de \”Compra efectuada\”, y el servicio responsable de enviar la factura por mail la va a procesar de una forma asíncrona. Esto permite el re-procesamiento de eventos en caso de fallas, evita una carga intensiva de la red; y nos garantiza que, en caso de que el servicio de envíos de mail falle, la compra igual se procese y no comprometa toda la transacción.
¿Entonces?
La decisión de microservicios sí o microservicios no va a depender de cada empresa, equipo y negocio. Pensar en frío y establecer cuáles son las ventajas y desventajas que traería al equipo es la mejor manera de empezar. Las modas son pasajeras y lo que hoy esta de moda, mañana cambia. Una decisión bien pensada y documentada siempre va a tener un buen impacto.
Sobre el autor: Soy Pablo Morelli, humano, 28 años, nativo de Argentina y viviendo en Suecia. Trabajo hace 7 años en IT como backend y devops. Me gusta el pádel y los videojuegos. Si te gustó este artículo, te invito a suscribirte al podcast Stream404 en Youtube y a seguirnos en Twitter. Este es un proyecto que estamos llevando a cabo entre amigos con episodios mensuales en vivo. Si me queres agregar en tu feed, también podés seguirme en mi blog.