En algunas publicaciones recientes del blog, hemos explicado por qué creemos que es fundamental adoptar una arquitectura de aplicaciones de cuatro niveles en la que las aplicaciones se desarrollen e implementen como conjuntos de microservicios. Cada vez está más claro que, si se siguen utilizando procesos de desarrollo y arquitecturas de aplicaciones que funcionaban perfectamente hace diez años, sencillamente no se puede avanzar con la rapidez suficiente para captar y mantener el interés de los usuarios de dispositivos móviles, que pueden elegir entre un número cada vez mayor de aplicaciones.
La transición a una arquitectura de microservicios brinda a las empresas interesantes oportunidades en el mercado. Para los arquitectos de sistemas y los desarrolladores, supone un nivel de control y velocidad sin precedentes a la hora de ofrecer a los clientes nuevas experiencias web innovadoras. Sin embargo, a un ritmo tan vertiginoso, puede parecer que apenas hay margen de error. En la práctica, no se puede detener el desarrollo y el despliegue de las aplicaciones mientras se reformulan los procesos para llevarlos a cabo. Sabe que su éxito futuro depende de la transición a una arquitectura de microservicios, pero ¿cómo se hace realmente?
Afortunadamente, varios de los primeros en adoptar los microservicios comparten ahora generosamente sus conocimientos siguiendo el espíritu del código abierto, no solo mediante la publicación de código, sino también a través de ponencias en conferencias y artículos de blog. Netflix es un ejemplo destacado. Como director de Ingeniería Web y, posteriormente, arquitecto de la nube, Adrian Cockcroft supervisó la transición de la empresa desde un modelo de desarrollo tradicional, con 100 ingenieros que producían una aplicación monolítica de alquiler de DVD, hasta una arquitectura de microservicios con numerosos equipos pequeños responsables del desarrollo integral de cientos de microservicios que trabajan conjuntamente para ofrecer contenidos de entretenimiento digital en streaming a millones de clientes de Netflix cada día. Actualmente, como Technology Fellow en Battery Ventures, Cockcroft es un destacado defensor de los microservicios y las arquitecturas nativas de la nube, y forma parte del Consejo Asesor Técnico de NGINX.
En una serie de dos entradas de blog, presentaremos las principales conclusiones de dos charlas que Cockcroft impartió el año pasado: una en octubre, durante la primera conferencia anual de NGINX, y otra un par de meses antes, en un encuentro sobre microservicios de Silicon Valley. (También merece mucho la pena ver las grabaciones completas en vídeo).
- Este artículo define la arquitectura de microservicios y describe algunas prácticas recomendadas para diseñarla.
- La adopción de microservicios en Netflix: lecciones para el diseño de equipos y procesos analiza por qué y cómo adoptar una nueva mentalidad para el desarrollo de software y reorganizar los equipos en torno a ella.
¿Qué es una arquitectura de microservicios?
Cockcroft define una arquitectura de microservicios como una «arquitectura orientada a servicios compuesta por elementos débilmente acoplados que tienen contextos delimitados».
Débilmente acoplados significa que puedes actualizar los servicios de forma independiente; actualizar un servicio no requiere modificar ningún otro. Si tienes un conjunto de servicios pequeños y especializados, pero aun así debes actualizarlos juntos, no son microservicios porque no están débilmente acoplados. Un tipo de acoplamiento que suele pasarse por alto durante la transición a una arquitectura de microservicios es el acoplamiento de la base de datos, en el que todos los servicios se comunican con la misma base de datos y actualizar un servicio implica cambiar el esquema. Debes dividir la base de datos y desnormalizarla.
El concepto de contextos delimitados procede del libro Domain Driven Design de Eric Evans. Un microservicio con un contexto correctamente delimitado es autónomo a efectos del desarrollo de software. Se puede comprender y actualizar el código del microservicio sin saber nada sobre el funcionamiento interno de sus homólogos, ya que el microservicio y estos interactúan exclusivamente a través de API y, por tanto, no comparten estructuras de datos, esquemas de bases de datos ni otras representaciones internas de objetos.
Si has desarrollado aplicaciones para Internet, ya estarás familiarizado con estos conceptos, aunque sea en la práctica y no por su nombre. La mayoría de las aplicaciones móviles se comunican con numerosos servicios de backend para que sus usuarios puedan hacer cosas como compartir contenido en Facebook, obtener indicaciones de Google Maps y buscar restaurantes en Foursquare, todo ello sin salir de la aplicación. Si tu aplicación móvil estuviera estrechamente acoplada a esos servicios, antes de publicar una actualización tendrías que hablar con todos sus equipos de desarrollo para asegurarte de que tus cambios no vayan a causar ningún problema.
Cuando se trabaja con una arquitectura de microservicios, se considera a los demás equipos de desarrollo internos como si fueran esos backends de Internet: servicios externos con los que el microservicio interactúa mediante API. El «contrato» comúnmente aceptado entre los microservicios establece que sus API deben ser estables y compatibles con versiones futuras. Del mismo modo que resulta inaceptable que la API de Google Maps cambie sin previo aviso y de forma que deje de funcionar para sus usuarios, una API puede evolucionar, pero debe seguir siendo compatible con las versiones anteriores.
Mejores prácticas para diseñar una arquitectura de microservicios
Cockcroft describe su función como arquitecto de la nube en Netflix no como alguien que controla la arquitectura, sino como quien descubre y formaliza la arquitectura que fue surgiendo a medida que los ingenieros de Netflix la construían. El equipo de desarrollo de Netflix estableció varias prácticas recomendadas para diseñar e implementar una arquitectura de microservicios.
Cree un almacén de datos independiente para cada microservicio
No utilice el mismo almacén de datos de backend para varios microservicios. Es preferible que el equipo responsable de cada microservicio elija la base de datos que mejor se adapte al servicio. Además, con un único almacén de datos, es demasiado fácil que los microservicios desarrollados por distintos equipos compartan estructuras de base de datos, quizá con el objetivo de evitar duplicar el trabajo. Esto provoca que, si un equipo actualiza una estructura de base de datos, también haya que modificar los demás servicios que la utilizan.
Separar los datos puede complicar su gestión, ya que los distintos sistemas de almacenamiento pueden desincronizarse o presentar incoherencias con mayor facilidad, y las claves externas pueden cambiar de forma inesperada. Es necesario añadir una herramienta que lleve a cabo la gestión de datos maestros (MDM) y que se ejecute en segundo plano para detectar y corregir incoherencias. Por ejemplo, podría examinar todas las bases de datos que almacenan identificadores de suscriptores para comprobar que los mismos identificadores existan en todas ellas (es decir, que no falte ni sobre ninguno en ninguna base de datos). Puede desarrollar su propia herramienta o adquirir una. Muchos sistemas comerciales de gestión de bases de datos relacionales (RDBMS) realizan este tipo de comprobaciones, pero suelen imponer demasiados requisitos de acoplamiento y, por tanto, no son escalables.
Mantén el código en un nivel de madurez similar
Mantén todo el código de un microservicio en un nivel similar de madurez y estabilidad. En otras palabras, si necesitas añadir o reescribir parte del código de un microservicio desplegado que funciona bien, el mejor enfoque suele ser crear un nuevo microservicio para el código nuevo o modificado y mantener el microservicio existente tal como está. [Editor: Esto se conoce a veces como el principio de infraestructura inmutable.] De este modo, puedes desplegar y probar el nuevo código de forma iterativa hasta que no tenga errores y alcance la máxima eficiencia, sin arriesgarte a que se produzcan fallos o se degrade el rendimiento del microservicio existente. Cuando el nuevo microservicio sea tan estable como el original, puedes volver a fusionarlos si realmente desempeñan juntos una única función o si combinarlos aporta otras mejoras de eficiencia. Sin embargo, según la experiencia de Cockcroft, es mucho más habitual darse cuenta de que conviene dividir un microservicio porque ha crecido demasiado.
Realiza una compilación independiente para cada microservicio
Realice una compilación independiente para cada microservicio, de modo que pueda obtener del repositorio los archivos de los componentes en los niveles de revisión adecuados. En ocasiones, esto hace que varios microservicios obtengan un conjunto similar de archivos, pero con distintos niveles de revisión. Esto puede dificultar la limpieza del código base al retirar versiones antiguas de los archivos (porque hay que comprobar con más cuidado que una revisión ya no se utiliza), pero es una contrapartida aceptable dada la facilidad con la que se pueden añadir nuevos archivos al crear nuevos microservicios. La asimetría es intencionada: añadir un nuevo microservicio, archivo o función debe ser fácil, no peligroso.
Despliegue en contenedores
Desplegar microservicios en contenedores es importante porque permite utilizar una única herramienta para desplegarlo todo. Siempre que el microservicio esté en un contenedor, la herramienta sabrá cómo desplegarlo, independientemente del tipo de contenedor. Dicho esto, Docker parece haberse convertido muy rápidamente en el estándar de facto para los contenedores.
Trata los servidores como entidades sin estado
Trate los servidores, especialmente aquellos que ejecutan código de cara al cliente, como miembros intercambiables de un grupo. Todos realizan las mismas funciones, por lo que no es necesario preocuparse por cada uno de ellos de forma individual. Lo único que debe importarle es que haya suficientes para gestionar la carga de trabajo necesaria; puede utilizar el escalado automático para aumentar o reducir su número. Si uno deja de funcionar, se sustituye automáticamente por otro. Evite los sistemas «copo de nieve», en los que se depende de servidores concretos para realizar funciones especializadas.
La analogía de Cockcroft consiste en pensar en los servidores como ganado, no como mascotas. Si tienes una máquina en producción que desempeña una función especializada, la conoces por su nombre y todo el mundo se entristece cuando deja de funcionar, es una mascota. En cambio, deberías pensar en tus servidores como un rebaño de vacas. Lo que importa es cuántos litros de leche obtienes. Si un día observas que obtienes menos leche de lo habitual, averiguas qué vacas no están produciendo bien y las sustituyes.
La arquitectura de distribución de Netflix se basa en NGINX
Netflix lleva mucho tiempo utilizando NGINX Open Source y se convirtió en el primer cliente de NGINX, Inc. tras su constitución en 2011. De hecho, Netflix eligió NGINX como núcleo de su infraestructura de distribución, Open Connect, una de las mayores redes de distribución de contenidos (CDN) del mundo. Gracias a su capacidad para atender miles, y en ocasiones millones, de solicitudes por segundo, NGINX y NGINX Plus son soluciones óptimas para la distribución HTTP de alto rendimiento y permiten a empresas como Netflix ofrecer experiencias digitales de alta calidad a millones de clientes cada día.
Grabaciones de vídeo
Entrega rápida
nginx.conf 2014, octubre de 2014
Migración a microservicios, parte 1
Encuentro sobre microservicios de Silicon Valley, agosto de 2014
Migración a microservicios, parte 2
Encuentro de microservicios de Silicon Valley, agosto de 2014
Sobre el autor
Artículos relacionados del blog
Únete a F5 NGINX en AppWorld 2024
Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.
Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.
Exposición de APIs en Kubernetes
La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».
NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.
Presentamos NGINX Plus R22
NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.
Presentamos NGINX Plus R17
NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.