¿Qué es una arquitectura de microservicios?
Se trata de una aproximación que consiste en construir una aplicación como un conjunto de pequeños servicios independientes entre sí. Cada uno de ellos, debe de tener una funcionalidad propia y la suma de todos ellos dará como resultado la aplicación deseada…sencillo, ¿verdad?
Un poquito de historia
En la década de los 80, nace el concepto “Remote procedure protocol”. La idea básica era la de hacer llamadas remotas transparentes para los desarrolladores, para que éstos no tuviesen que conocer si las llamadas o métodos se encontraban en una máquina local o no. La sobrecarga en la red superó las ventajas de la distribución y de este desaguisado salió el patrón Fachada, cuya finalidad es la de encapsular las interfaces no estructuradas para mejorar el consumo de este. Esto plantea un problema cuando todo el código no comparte la misma lengua matter, es decir, todos los sistemas distribuidos deben estar programados con el mismo lenguaje.
A esto le siguió SOAP y WS– (ambos descartados porque la industria vio que se volvían difíciles de manejar) y llegó entonces una adopción masiva a Representational State Transfer, más conocido como REST, cuyo principio era tratar al HTTP respetando sus convicciones: respetar verbos (GET, POST, PUT, PATCH, …), los códigos HTTP (200 OK, 503 Unavailable), etcétera.
Señas identificativas
Haciendo uso de lo que autores de renombre promueven, podríamos asegurar que una arquitectura implementada en microservicio responde a los siguientes principios:
- Cada parte de un negocio es gestionada por un microservicio.
- Cada servicio debe de poder desplegarse y escalarse de manera independiente, sin que el 100% de la aplicación se vea afectada.
- Cada servicio se debe a conseguir un objetivo concreto, por lo que cada servicio puede estar implementado con un lenguaje distinto.
Ejemplo
Supongamos que tenemos que gestionar una empresa de alquiler de vehículos. Vamos a centrarnos en tres departamentos en concreto: rrhh, oficinas de alquiler y gestión de flota. Hagamos una definición de cada uno de los departamentos:
- RRHH gestiona el personal de la empresa.
- En las oficinas de alquiler, el personal alquila vehículos a particulares.
- Los gestores de flota se encargan de controlar el stock de vehículos.
Ahora pensemos en un posible esquema monolítico para la base de datos:
Vale, repasemos: los empleados de RRHH dan de alta/baja al resto de los empleados. Los jefes de flota dan de alta a los coches que tienen asignados en su cartera y los empleados de venta alquilan los coches, por lo que entre Employees y Vehicles saldrá una tabla muchos a muchos.
De momento el cliente tiene una oficina, pero como se ha acabado la COVID y los gobiernos han incentivado tanto el turismo se está expandiendo muy rápido, tan rápido que ahora quieren una web y van a abrir 150 oficinas por toda Europa… ¿Se empieza a intuir el problema?
Una solución rápida podría ser meter este diseño en una máquina virtual, reinvertir la mitad de la inversión del gobierno en RAM y ancho de banda y empezar a operar, pero ¿por qué si la única función de RRHH es dar de alta/baja a empleados debe de compartir unos costes tan elevados? ¿Va a tener la web que tener acceso a la base de datos de vehículos, a la vez que los empleados de oficina? Los jefes de flota, por como hemos planteado el ejemplo, únicamente se encargan de controlar la disposición geográfica de los vehículos. ¿Si sólo les interesa ese dato, por qué deben de acceder en la consulta a la misma tabla que los empleados de oficina?
Además, se rumorea que se va a empezar a disponer de un servicio propio de mecánicos que también van a tener que acceder a la misma tabla de vehículos y que la web dará paso a una aplicación móvil.
Ahora pensemos en dividir la aplicación en pequeños microservicios:
Si nos damos cuenta, esa gran base de datos, la hemos dividido. Ahora RRHH únicamente gestiona a los empleados en su módulo, con lo que ese coste se ha disminuido.
Los empleados de oficina acceden a sus datos locales de vehículos y la web ayuda a los gestores a decidir cómo balancear la carga de vehículos dentro de las distintas sedes. Mira como ahora ni tan siquiera necesitaríamos que todas las bases de datos tuviesen el mismo motor.
Por otra parte, si la compañía finalmente adquiriese un servicio de taller, se crearía otro servicio únicamente para que los mecánicos tengan la información que necesitan sobre los vehículos.
Es común que varias áreas de una empresa hagan uso de un mismo concepto (como podría ser “vehículo”). Lo relevante es que únicamente se deben de sincronizar aquellos elementos que tengan sentido. Por ejemplo, desde la web no se deben de poder ver las matrículas de los coches, simplemente deben de tener acceso a modo de lectura de las características de los vehículos para que el cliente sepa las características de los coches que puede alquilar.
Esta forma de proceder también nos permite balancear la carga de los recursos de la aplicación, por lo que puede ser que los microservicios de los empleados de ventas requieran más potencia en horario comercial de lunes a sábado y RRHH únicamente de lunes a viernes mientras que la web, en función de su uso se pueda escalar para que tenga más potencia en periodo de pretemporada.
Los microservicios son la arquitectura que eclipsará al resto
Respuesta corta: ¡NO!
Respuesta larga: No, cada problema y cada contexto tienen una solución óptima.
Aunque es cierto que grandes éxitos empresariales (Ebay, Amazon, Netflix) han popularizado este término, hay que tener en cuenta que este tipo de arquitecturas son complejas (no por ello más complicada) y es necesario usarlas cuando, por ejemplo, se espera una carga masiva de tráfico, o cuando se estima que la aplicación va a tener un rápido crecimiento o que determinadas áreas van a hacer un uso más intensivo de los recursos.
La complejidad de la arquitectura está relacionada en que hay que pensar en “distribuido”: división correcta de microservicios, comunicación entre microservicios, definición de acción tras error (circuit breaker), sistemas de cola y su gestión de errores, etcétera.