Arquitecturas monolíticas y de microservicios

Completado

Fabrikam ha integrado el nuevo servicio de drones en su aplicación existente. Saben que esta solución no es un buen plan a largo plazo para su aplicación. El sistema existente es una arquitectura monolítica, pero ¿qué significa eso exactamente?

¿Qué es una arquitectura monolítica?

Una arquitectura monolítica es aquella en la que todos los componentes de una aplicación se colocan en una sola unidad. Normalmente esta unidad está restringida dentro de una única instancia en tiempo de ejecución de la aplicación. Las aplicaciones tradicionales suelen constar de una interfaz web, una capa de servicios y una capa de datos. En una arquitectura monolítica, estas capas se combinan en una instancia de la aplicación.

Logical diagram of a monolithic architecture.

Las arquitecturas monolíticas suelen ser soluciones adecuadas para aplicaciones pequeñas, pero pueden resultar difíciles de manejar a medida que crece la aplicación. Lo que originalmente era una aplicación pequeña, se puede convertir rápidamente en un sistema complejo difícil de escalar, implementar e innovar.

Todos los servicios se encuentran en una sola unidad. Esta disposición supone un desafío, especialmente cuando aumenta el negocio y la carga posterior del sistema. Algunos de estos desafíos son los siguientes:

  • Dificultad para escalar los servicios de forma independiente.
  • Dificultad para desarrollar y administrar implementaciones a medida que aumenta el código base, lo que reduce las versiones y la implementación de características nuevas.
  • La arquitectura se vincula a una sola pila de tecnología, lo que limita la innovación en nuevas plataformas y SDK.
  • Las actualizaciones del esquema de datos pueden ser cada vez más difíciles.

Estos desafíos se pueden solucionar si se examinan arquitecturas alternativas, como una arquitectura de microservicios.

¿Qué es una arquitectura de microservicios?

Una arquitectura de microservicios consta de servicios pequeños, independientes y acoplados de forma flexible. Cada servicio se puede implementar y escalar de manera independiente.

Logical diagram of a microservices architecture.

Un microservicio es lo suficientemente pequeño como para que un único equipo reducido de programadores lo pueda escribir y mantener. Como los servicios se pueden implementar de forma independiente, un equipo puede actualizar un servicio existente sin tener que volver a generar e implementar toda la aplicación.

Cada servicio suele ser responsable de sus propios datos. Su estructura de datos está aislada, de modo que las actualizaciones o los cambios en el esquema no dependen de otros servicios. Normalmente, las solicitudes de datos se controlan a través de API y proporcionan un modelo de acceso coherente y bien definido. Los detalles internos de la implementación se ocultan a los consumidores del servicio.

Como cada servicio es independiente, pueden usar otras pilas de tecnología, marcos y SDK. Es habitual ver que los servicios se basan en llamadas REST para la comunicación entre servicios mediante API bien definidas en lugar de llamadas a procedimiento remoto (RPC) u otros métodos de comunicación personalizados.

Las arquitecturas de microservicios son independientes de la tecnología, pero a menudo verá que se usan contenedores o tecnologías sin servidor para su implementación. La implementación y la integración continuas (CI/CD) se usan con frecuencia para aumentar la velocidad y la calidad de las actividades de desarrollo.

Ventajas de una arquitectura de microservicios

¿Por qué elegiría una arquitectura de microservicios? Una arquitectura de microservicios ofrece varias ventajas principales:

  • Agilidad
  • Código pequeño, equipos pequeños
  • Mezcla de tecnologías
  • Resistencia
  • Escalabilidad
  • Aislamiento de datos

Agilidad

Como los microservicios se implementan de forma independiente, las correcciones de errores y las versiones de características resultan más fáciles de administrar. Puede actualizar un servicio sin volver a implementar toda la aplicación y revertir una actualización si se produce algún error. En muchas aplicaciones tradicionales, si se detecta un error en una parte de la aplicación, puede bloquear el proceso de la versión completa. Como resultado, las características nuevas se pueden detener a la espera de la integración, prueba y publicación de una corrección del error.

Código pequeño, equipos pequeños

Un microservicio debe ser lo suficientemente pequeño como para que un solo equipo de características lo pueda compilar, probar e implementar. Las bases de código pequeñas son más fáciles de entender. En una gran aplicación monolítica, las dependencias de código tienden a complicarse con el tiempo. Para agregar una característica nueva, es necesario modificar el código en muchos lugares. Al no compartir el código ni los almacenes de datos, una arquitectura de microservicios minimiza las dependencias. Esto facilita la adición de características nuevas.

Los equipos pequeños favorecen la agilidad. La regla de las dos pizzas establece que el equipo debe ser lo suficientemente pequeño para que se alimente con dos pizzas. Obviamente, no es una métrica exacta y depende del apetito del equipo. Pero lo que se quiere decir es que los grupos grandes suelen ser menos productivos, porque la comunicación es más lenta, la administración se sobrecarga y la agilidad disminuye.

Mezcla de tecnologías

Los equipos pueden elegir la tecnología que mejor se adapte a su servicio. Pueden usar una combinación de pilas de tecnología según corresponda. Cada equipo puede desarrollar las tecnologías que admitan su servicio de forma independiente. Debido a esta independencia, los servicios pueden usar diferentes lenguajes de desarrollo, servicios en la nube, SDK, etc. Los equipos pueden elegir las mejores opciones para su servicio, a la vez que se minimiza cualquier efecto externo en los consumidores del servicio.

Resistencia

Si un microservicio individual no está disponible, no interrumpe toda la aplicación, siempre que los microservicios de nivel superior estén diseñados para controlar los errores de forma correcta (por ejemplo, mediante la implementación de disyuntores). La ventaja para los usuarios o los consumidores del servicio es una experiencia de actividad continua para la aplicación.

Escalabilidad

Una arquitectura de microservicios permite el escalado independiente de cada microservicio. Puede escalar horizontalmente los subsistemas que requieren más recursos, sin tener que escalar horizontalmente toda la aplicación. Esto mejora el rendimiento general de la aplicación. También ayuda a minimizar los costos. Puede agregar más recursos solo a los servicios que los necesitan, en lugar de escalar verticalmente toda la aplicación.

Aislamiento de datos

Una arquitectura de microservicios mejora la posibilidad de realizar actualizaciones del esquema de datos, ya que solo se ve afectado un microservicio. En una aplicación monolítica, las actualizaciones del esquema pueden ser muy complicadas. Es posible que distintos elementos de la aplicación trabajen con los mismos datos, por lo que resulta peligroso realizar modificaciones en el esquema. Con una arquitectura de microservicios puede actualizar un esquema, pero mantener intacta la superficie de la API. Los consumidores del servicio tendrán la misma experiencia, con independencia de la arquitectura de datos subyacente.

Posibles desafíos de una arquitectura de microservicios

Una arquitectura de microservicios ofrece muchas ventajas, pero no es una solución definitiva. Una arquitectura de microservicios aporta su propio conjunto de desafíos:

  • Complejidad
  • Desarrollo y pruebas
  • Falta de gobernanza
  • Congestión y latencia de la red
  • Integridad de datos
  • Administración
  • Control de versiones
  • Conjunto de aptitudes

Complejidad

Una aplicación de microservicios tiene más elementos dinámicos que la aplicación monolítica equivalente. Cada servicio es más sencillo, pero de forma global, el sistema es más complejo. Con las herramientas de detección, orquestación y automatización de servicios, puede haber más partes que administrar en la aplicación global.

Desarrollo y pruebas

La escritura de un servicio pequeño que se base en otros servicios dependientes requiere un enfoque diferente al de escribir una aplicación tradicional monolítica o en capas. Las herramientas existentes no siempre están diseñadas para trabajar con dependencias de servicios. La refactorización en los límites del servicio puede resultar difícil. También supone un desafío probar las dependencias de los servicios, especialmente cuando la aplicación evoluciona rápidamente.

Falta de gobernanza

El enfoque descentralizado para la generación de microservicios tiene ventajas, pero también puede causar problemas. Es posible que acabe con multitud de lenguajes y marcos de trabajo diferentes que dificulten el mantenimiento de la aplicación. Podría resultar útil establecer algunos estándares para todo el proyecto, sin restringir en exceso la flexibilidad de los equipos. La necesidad de estándares uniformes se aplica especialmente a las funcionalidades transversales, como el registro y las métricas.

Congestión y latencia de la red

El uso de muchos servicios pequeños y pormenorizados puede dar lugar a una mayor comunicación entre los servicios. Si la cadena de dependencias del servicio se hace demasiado larga (por ejemplo, el servicio A llama a B, que llama a C...), la latencia adicional de estas llamadas de red puede suponer un problema. Diseñe las API con atención. Evite que las API se comuniquen en exceso, piense en formatos de serialización y busque lugares para usar patrones de comunicación asincrónica.

Integridad de datos

Cada microservicio es responsable de la conservación de sus propios datos. Como consecuencia, la coherencia de los datos puede suponer un problema. Adopte una coherencia final cuando sea posible. También puede acabar con datos duplicados y una arquitectura de datos en expansión. Esta situación puede aumentar los costos iniciales de almacenamiento y los del servicio de plataforma de datos debido a la duplicación de datos y servicios.

Administración

Para trabajar de forma correcta con los microservicios se necesita una cultura de DevOps consolidada. El registro correlacionado entre servicios puede resultar un desafío. Normalmente, el registro debe correlacionar varias llamadas de servicio para una sola operación de usuario.

Control de versiones

Las actualizaciones de un servicio no deben interrumpir servicios que dependan de él. Es posible que varios servicios se actualicen en un momento dado. Sin un diseño cuidadoso, es posible que surjan problemas con la compatibilidad con versiones anteriores o posteriores. Los servicios que se retrasen en la adopción de nuevas versiones de API pueden aumentar los recursos y el mantenimiento necesarios para las API anteriores.

Conjunto de aptitudes

Los microservicios son sistemas muy distribuidos. Estos sistemas distribuidos a menudo requieren otro conjunto de aptitudes para desarrollarlos, administrarlos y mantenerlos de forma correcta. Evalúe con atención si el equipo tiene los conocimientos y la experiencia para desenvolverse correctamente. Permita que los equipos tengan el tiempo y la planificación que necesitan para desarrollar sus capacidades.

¿Cuándo debería elegir una arquitectura de microservicios?

En función de esta información general, ¿para qué situaciones resulta más adecuada una arquitectura de microservicios?

  • Aplicaciones grandes que requieren una velocidad de publicación elevada.
  • Aplicaciones complejas que necesitan ser muy escalables.
  • Aplicaciones con dominios enriquecidos o muchos subdominios.
  • Una organización formada por pequeños equipos de desarrollo.