En una publicación anterior, hablamos sobre cómo los servicios en la nube se han convertido en un estándar no escrito para proporcionar servicios de TI. Es fácil adivinar que las empresas que aún quieren ganar dinero con las aplicaciones de los usuarios deben adaptarse y crear nuevos productos teniendo en cuenta el enfoque nativo de la nube. Sin embargo, para los desarrolladores esta es definitivamente una noticia positiva, ya que el uso de tecnologías en la nube les abre nuevas y enormes oportunidades. Lo principal es poder deshacerse de ellos correctamente.
Cuando una aplicación ordena un entorno
Si ya ha leído la
guía de tecnología en la nube, probablemente recordará que la tecnología de virtualización es una de las "fuentes mágicas" de las nubes. Gracias a esto, el desarrollador prácticamente no necesita pensar en los parámetros de los servidores en los que funcionará su aplicación. ¿Por qué dedicar tiempo a esto si un hipervisor o contenedor configurado correctamente puede configurar una máquina con casi cualquier característica que la aplicación necesite para funcionar?
El desarrollo de esta idea es el enfoque de Infraestructura como código (IAC). Su esencia es permitir que los desarrolladores o servicios operativos usen los mismos enfoques que se usan durante la fase de desarrollo para mantener la infraestructura. Le permite preparar unidades de control de software comunes por adelantado e integrar fácilmente dichos componentes en nuevos proyectos.
Las capacidades de los centros de datos modernos ya nos permiten pasar al lenguaje declarativo de la gestión de la infraestructura. Idealmente, la aplicación debería administrar el grupo de recursos que ocupa en el centro de datos. Esto permitirá que el desarrollador no quede bloqueado en las limitaciones asociadas con el proceso de trabajar con la infraestructura, cuando sea necesario ordenar y diseñar con anticipación o si los mismos componentes de la infraestructura se repiten en diferentes proyectos.

De hecho, el desarrollador o ingeniero realiza una solicitud de extracción, que contiene la configuración de la máquina virtual (kernel, memoria, red, plantilla, etc.), luego el administrador del entorno virtual crea la máquina de forma independiente o crea una nueva instancia de base de datos o inicia el servicio preinstalado, de acuerdo con la configuración en archivo. Este enfoque es una verdadera salvación cuando se trabaja con big data y redes neuronales. Las aplicaciones asociadas con estas tecnologías, en algunos casos, requieren cantidades dinámicamente cambiantes de memoria y potencia del procesador.
Por ejemplo, para entrenar una red, es necesario "manejar" cientos de gigabytes de información a través de ella, y las nubes le permiten obtener la capacidad requerida para esto a pedido. Una vez completada la capacitación, los recursos se devuelven al grupo de proveedores y el desarrollador no necesita pensar qué hacer con ellos o cómo configurar la aplicación de otra manera para que continúe funcionando a menor capacidad.
Monolito vs. caos ordenado
Debido al hecho de que las nubes pueden adaptarse de manera flexible a las necesidades del desarrollador, esto, en teoría, simplifica otra tarea: el problema de escalar aplicaciones. ¿Por qué teóricamente?
Desafortunadamente, la tarea de escalar aplicaciones no es lineal. Para que la aplicación pueda hacer frente a grandes cargas durante los períodos de máxima asistencia (o computación), no es suficiente solo darle memoria adicional y potencia de procesador. Absolutamente cada aplicación tradicional tiene un umbral, después del cual ya no puede "digerir" nuevos recursos y demostrar un aumento en el rendimiento. El problema en este caso no son los recursos, sino la arquitectura de la mayoría de los programas.
Este problema es especialmente grave para aplicaciones con una arquitectura monolítica, que, de hecho, son archivos binarios únicos. Las ventajas de este enfoque son obvias: las aplicaciones monolíticas son bastante simples y lineales. Todos los escenarios de comportamiento del usuario pueden predecirse, rastrearse y, si es necesario, depurarse.
Sin embargo, tal simplicidad tiene un precio. En primer lugar, estos son los problemas de escalamiento mencionados anteriormente. En algún momento, incluso la aplicación monolítica más considerada deja de funcionar de manera más eficiente a partir de una actualización de la configuración del servidor en la que se ejecuta.
En segundo lugar, una aplicación monolítica no es tan fácil de transferir a nuevos servidores y esto puede requerir una recompilación completa del programa.
En tercer lugar, dicha aplicación es difícil de mantener y desarrollar. Cualquier cambio de actualización requiere el ensamblaje completo de todo el programa, y un error en uno de los bloques de código puede provocar la caída de todo el sistema.
En busca de ideas sobre cómo resolver estos problemas, se desarrolló otro concepto: la arquitectura orientada a servicios (SOA). Implica que la aplicación se divide en varios módulos, cada uno de los cuales proporciona a los demás algún tipo de funcionalidad. Los módulos interactúan entre sí a través de un conjunto de servicios web y pueden acceder de forma independiente a una o sus propias bases de datos.
Este enfoque realmente simplifica el soporte del programa y no convierte su actualización "en el trabajo de un zapador", en el que no hay lugar para el error; pero él también tiene sus defectos. La clave son los problemas para escalar el desarrollo de tales aplicaciones. A medida que el programa crece, se hace cada vez más difícil "insertar" nuevas características en los paquetes 5-10 aprobados originalmente por el arquitecto. Su número está creciendo, lo que se convierte en problemas con el apoyo.
El microservicio como elemento de evolución de la aplicación.
El resultado de la evolución de SOA es la idea de la arquitectura de microservicios, que se utiliza en el diseño de aplicaciones en la nube. Conceptualmente, las ideas de ambos enfoques son extremadamente similares, y algunos arquitectos ni siquiera seleccionan la arquitectura de microservicios como un paradigma separado, considerándolo un caso especial de SOA.
La arquitectura de microservicios implica que la aplicación no consta de una pequeña cantidad de módulos grandes, sino de muchas partes independientes. A diferencia de un monolito, en una aplicación de microservicio, puede usar varios métodos para la interacción de componentes entre sí. El sistema no tiene un solo estado predeterminado. En cambio, cada componente funciona "de acuerdo con la situación": tan pronto como recibe un evento, comienza a funcionar. Esto permite una arquitectura muy flexible e independiente.
Al mismo tiempo, la cantidad de servicios en la aplicación de microservicios cambia constantemente: algunos se agregan y otros se eliminan. En el nuevo enfoque, cualquier microservicio puede ser reemplazado y una cadena de microservicios incrustada en su lugar. Otros servicios continúan funcionando de manera estable, porque no están directamente relacionados. Esta es la evolución natural del programa. Gracias a esto, los desarrolladores y arquitectos tienen la oportunidad de cambiar algo rápidamente para responder a los cambios en los requisitos comerciales y superar a los competidores.
Además de aumentar la velocidad de actualización de actualizaciones, el uso de la arquitectura de microservicios permite una administración descentralizada. El equipo responsable del desarrollo de un servicio tiene derecho a determinar su arquitectura interna y sus características. Tal enfoque, por cierto, ahora está siendo implementado por el Consejo de Arquitectura de Sberbank en el Bloque de Tecnología.
Al mismo tiempo, siéntate a desarrollar tu aplicación en la nube, no debes apresurarte con la rapidez de aplastarla en sus elementos constitutivos. El principal oponente de un enfoque tan irreflexivo es Martin Fowler; Es uno de los autores de la idea de la arquitectura de microservicios. Es más fácil usar inicialmente un enfoque monolítico, y luego estimular la evolución de la aplicación de una manera "natural", enfocándose en la ruptura de cuellos de botella y la adición de funciones adicionales.
Como resultado, podemos formular la siguiente regla: la tarea del programador cuando trabaja con la arquitectura de microservicios no es solo dividir la aplicación en el número máximo de componentes, sino distinguir deliberadamente entre su responsabilidad de recibir y procesar datos.
Cuatro detalles
Además de las muchas ventajas obvias, la arquitectura de microservicios tiene sus propias características, que deben tenerse en cuenta al desarrollar su aplicación en la nube. En particular, para respaldar el funcionamiento de una aplicación de este tipo, es necesario mantener constantemente requisitos crecientes para la calidad de la gestión de las API internas.
Cuando uno de los componentes cambia su interfaz, debe admitir la compatibilidad con versiones anteriores para admitir la versión anterior de su propia API. Si se observa esta regla, puede cambiar dinámicamente de la versión anterior a la nueva sin fallas. Si no se resuelve el soporte para la versión anterior de la API, esto amenaza, en el mejor de los casos, con la pérdida de parte de la funcionalidad de la aplicación y, en el peor de los casos, con bloqueos permanentes en su funcionamiento.
La segunda característica importante de las aplicaciones de microservicios es la dificultad de encontrar errores en ellas. Si una aplicación escrita en lógica monolítica o SOA se bloquea, no será difícil encontrar la fuente del problema. En una aplicación que consta de muchos servicios, la búsqueda de la causa del error puede llevar mucho tiempo debido al hecho de que los datos del usuario a menudo pasan por varios microservicios, y es difícil determinar cuál falla. Al mismo tiempo, el proceso de búsqueda de errores debe llevarse a cabo con mucho cuidado: cualquier refactorización fallida puede conducir a un colapso del módulo de trabajo y, además del problema inicial, el desarrollador recibirá un segundo.

El tercer detalle importante que debe tenerse en cuenta al desarrollar una aplicación en la nube es la forma en que sus componentes interactúan entre sí. Al igual que en SOA, los servicios utilizan servicios web para intercambiar datos, pero los patrones de interacción, como la transmisión, CQRS, el abastecimiento de eventos, han aparecido en la arquitectura de microservicios. Por lo general, los desarrolladores esperan que el tiempo de respuesta entre la solicitud y la respuesta en la aplicación sea bastante pequeño. En un sistema distribuido, uno ni siquiera puede confiar en el hecho de que la respuesta llegará en absoluto.
Además, en la arquitectura de las aplicaciones en la nube, los microservicios utilizan varias bases de datos que son las más adecuadas para resolver sus problemas específicos. Por ejemplo, las cuadrículas pueden leer rápidamente, pero difícilmente pueden hacer frente a una gran cantidad de operaciones de cambio de datos. Tal base es muy adecuada para mantener cuentas de depósito; rara vez cambian. Otro tipo de operación es el procesamiento; puede haber docenas de cambios en cada mapa en él todos los días y, por el contrario, hay pocas lecturas de datos.
Finalmente, el cuarto hecho que debe recordar al desarrollar una aplicación en la nube es que la arquitectura de microservicios se centra principalmente en el uso de servicios sin estado. En este caso, no vayas a los extremos. Algunos servicios, si es necesario, aún pueden proporcionar apoyo estatal si la lógica empresarial lo requiere, y deben diseñarse con especial cuidado.
Por ejemplo: si el usuario solicita un préstamo, el sistema que recibió la solicitud debe guardar este estado para transferirlo a otros servicios. Pero el servicio responsable de encontrar información en el archivo interno de historiales crediticios puede no guardar su estado y olvidarse de los datos sobre el nombre de usuario que buscó hace un par de minutos; de todos modos, después de un momento llegará una nueva solicitud (aunque en este proceso puede ser diferente comportamiento del servicio).
Todos los ejemplos y prácticas descritos anteriormente ya son utilizados activamente por los líderes de la industria global de TI. Por ejemplo, Netflix es pionero en el desarrollo de la arquitectura de microservicios. La compañía ha lanzado muchas aplicaciones de código abierto, bibliotecas y un marco para monitorear, equilibrar y registrar aplicaciones de microservicios.