Microservicios

Anamnesis de un motivado

Microservicios

Tradicionalmente, un software está compuesto por una parte cliente y una parte servidor. Esto quiere decir que parte se ejecuta en cliente y parte se ejecuta en servidor. Pero… ¿y si necesito ejecutar la parte cliente en mas de una plataforma?. Un usuario accede a Facebook desde su pc, tablet, smarPhone, smartTv. Esto se consigue haciendo clientes diferentes, uno para cada tipo dispositivo en el que se quiera poder ejecutar (plataforma).

Parece que la evolución solo ha afectado a la parte cliente, no?. La parte servidor la conocemos como una aplicación monolítica que está ejecutándose en un servidor. Cuando hay muchos clientes consumiéndola, se sobrecarga. Cuando hay pocos, va como un tiro pero está costando una pasta. Cuando hay que actualizarla, permanece fuera de servicio temporalmente (por tareas de mantenimiento). ¿Te suena eso, verdad?. Cuando hay un problema, búscalo en el monolito. Cuando hay muchos desarrolladores, resuelve conflictos al mergear. En fin… Nada es perfecto pero, parece que con este paradigma hay muchas dificultades, no?

Desde hace algún tiempo, la cosa parece que va evolucionando. No es que se haya inventado nada nuevo, simplemente se ha aplicado un poco de sentido común dando paso al paradigma de software basado en Microservicios. Esto es tan viejo como el «divide y vencerás». Consiste en coger todo el compendio de procesos que resuelve una parte servidor monolítica y dividirla en pequeñas partes servidor. Cada una de ellas va a resolver un problema muy concreto y todas ellas van a tener un marco común de comunicación.

Un ejemplo…

Creamos un API que recibe peticiones por el protocole http. Esas peticiones contienen mucha información pero solo nos interesa una parte de ella. La tratamos y extraemos solo la que nos interesa. Que puede ser la información de un usuario. Iremos persistiéndola en una base de datos MySql. ¿Qué pasa si por el motivo que sea, necesitamos cambiar el motor de base de datos a otra tecnología? Y además, no hay un driver de comunicación ya desarrollado para ese nuevo motor. Pues toca crearte un driver de comunicación para gestionar la conexión y modificar la parte de la aplicación encargada de escribir en MySql para que escriba en el nuevo motor. Luego sacar versión, tumbar la anterior y levantar la nueva. Menudo embrollo…

¿Y si… aplicamos el paradigma de microservicios?

Siguiendo el criterio de responsabilidad única… Lo primero es pelar la cebolla. Vamos a poner un servicio delante que haga de API y que reenvie todo lo que recibe a un segundo servicio. Este segundo solo va a extraer la información relevante y se la va a pasar a un tercero. Esta tercera capa solo va a escribir en MySql todo lo que reciba. En entre todos ellos la comunicación va a ser http y el único que va a ser visible por el cliente va a ser el API.

Y ahora repetimos la experiencia de aplicar la modificación del motor de bdd. Chupado!!. La única capa (microservicio), que tenemos que tocar es la tercera y además podemos escoger una tecnología que ya tenga un driver desarrollado (nodejs, java, golang, c#, etc).

¿Te lo pinto mejor? Resulta que el proceso que se encarga de extraer la información que nos interesa es pesado (computacionalmente hablando). Vamos… que hace muchas cosas y tarda incluso mas que el tiempo de escritura en disco. En el primer caso monolítico no nos queda otra que duplicar toda la app, y decirle a parte de nuestros clientes que ataquen a una y otros a la otra. ¿Y en microservicios? Solo duplicamos la capa central (la pesada). Y hacemos que la primera capa (API), balancee las peticiones a las réplicas.

Las principales desventajas.

  • Incremento en tiempo de datos en tránsito.
  • Requiere gran disciplina en mantener los contratos para la comunicación. De lo contrario podemos mermar la cohesión.

Por otro lado este nuevo paradigma tiene unas cuantas ventajas.

  • La parte servidora es tecnológicamente heterogénea. Siempre maximizando el rendimiento y la agilidad del desarrollo.
  • En su escalabilidad, solo replica la parte más congestionada, mejorando los costes de infraestructura.
  • Un refactorizado es siempre sobre una parte y no sobre un todo.
  • Al tener partes en diferentes repositorios previene los conflictos.
  • Ofrece mayor facilidad a la hora de implementar una seguridad perimetral ya que solo se exponen partes.
  • El criterio de responsabilidad única previene la duplicidad de código.
  • Desplegar una parte siempre será más rápido que desplegar un todo.
  • Menor acoplamiento