Mostrando entradas con la etiqueta Refactoring. Mostrar todas las entradas
Mostrando entradas con la etiqueta Refactoring. Mostrar todas las entradas

viernes, 11 de septiembre de 2020

De los Monolitos a los Microservicios

La mayoría de las empresas nuevas ejecutan sus procesos comerciales en La Nube. Las nuevas empresas emergentes y las empresas que se dieron cuenta lo suficientemente temprano de la dirección en la que se dirigía la tecnología desarrollaron sus aplicaciones para La Nube. 

No todas las empresas tuvieron tanta suerte. Algunos construyeron su éxito hace décadas sobre tecnologías heredadas: aplicaciones monolíticas con todos los componentes estrechamente acoplados y casi imposibles de separar, una pesadilla de administrar e implementar en hardware súper costoso.

Si trabaja para una organización que se refiere a su aplicación comercial principal "la caja negra", donde nadie sabe lo que sucede dentro y la mayor parte de la lógica nunca se documentó, dejando a todos sin idea de qué y cómo suceden las cosas desde el momento en que una solicitud ingresa a la aplicación hasta aparece una respuesta y se le asigna la tarea de convertir esta aplicación empresarial en un conjunto de aplicaciones listas para La Nube, entonces puede que se encuentre en un viaje muy largo y lleno de baches.

Los Monolitos Heredados

Aunque la mayoría de las empresas creen que La Nube será el nuevo hogar de las aplicaciones heredadas, no todas las aplicaciones heredadas son aptas para La Nube, o al menos no todavía.

Mover una aplicación a La Nube debería ser tan fácil como caminar por la playa y recoger guijarros en un balde y llevarlos fácilmente donde sea necesario. Una roca de 1,000 toneladas, por otro lado, no es nada fácil de transportar. Este bloque representa la aplicación monolítica: capas sedimentadas de características y lógica redundante, traducida en miles de líneas de código, escritas en un lenguaje de programación único, no tan moderno, basado en patrones y principios de arquitectura de software obsoletos.

Con el tiempo, las nuevas características y mejoras se sumaron a la complejidad del código, haciendo que el desarrollo sea más desafiante: los tiempos de carga, compilación y construcción aumentan con cada nueva actualización. Sin embargo, hay cierta facilidad en la administración ya que la aplicación se ejecuta en un solo servidor, idealmente una máquina virtual o un mainframe.

Lo Monolítico tiene un gusto bastante caro en hardware. Al ser una pieza de software grande y única que crece continuamente, debe ejecutarse en un solo sistema que debe satisfacer sus requisitos de cómputo, memoria, almacenamiento y redes. El hardware de tal capacidad suele ser complejo y caro.

Dado que toda la aplicación Monolítica se ejecuta como un solo proceso, la escalabilidad de las características individuales de este monolito es casi imposible. Admite internamente una cantidad codificada de conexiones y operaciones. Sin embargo, escalar toda la aplicación significa implementar manualmente una nueva instancia del monolito en otro servidor, generalmente detrás de un dispositivo para equilibrio de carga. Otra solución costosa.

Durante las actualizaciones, parches o migraciones de la aplicación Monolítica, se producen tiempos de inactividad y se deben planificar los períodos de mantenimiento, ya que se espera que las interrupciones en el servicio afecten a los clientes o usuarios. Si bien existen soluciones para minimizar los tiempos de inactividad hacia los clientes mediante la configuración de aplicaciones Monolíticas en una configuración activa/pasiva de alta disponibilidad, aún puede ser un desafío para los ingenieros de sistemas mantener todos los sistemas en el mismo nivel de actualización-versión-parche.

Los Microservicios Modernos

Los guijarros, a diferencia del canto rodado de 1,000 toneladas, son mucho más fáciles de manejar. Están tallados en el monolito, separados unos de otros, convirtiéndose en componentes distribuidos, cada uno descrito por un conjunto de características específicas. Una vez pesados ​​todos juntos, los guijarros constituyen el peso de toda la roca. Estos guijarros representan microservicios débilmente acoplados, en donde cada uno de los cuales realiza una función comercial específica. Todas las funciones agrupadas forman la funcionalidad general de la aplicación monolítica original. Los guijarros son fáciles de seleccionar y agrupar según el color, el tamaño y la forma, requiriendo un esfuerzo mínimo para reubicarlos cuando sea necesario. Intente reubicar la roca de 1000 toneladas sin un gran esfuerzo.

Los microservicios se pueden implementar individualmente en servidores separados y aprovisionados con menos recursos, con solo lo que requiere cada servicio y el propio sistema anfitrión (host).

La Arquitectura Basada en Microservicios (Microservices-Based Architecture) está alineada con los principios de Arquitectura Orientada a Eventos (AOE) y Arquitectura Orientada a Servicios (SOA), donde las aplicaciones complejas están compuestas por pequeños procesos independientes que se comunican entre sí a través de Application Programmable Interfaces (APIs), vía una red. Las APIs permiten el acceso de otros servicios internos de la misma aplicación o servicios y aplicaciones externos de terceros.

Cada microservicio se desarrolla y escribe en un lenguaje de programación moderno, seleccionado para ser el más adecuado para el tipo de servicio y su función comercial. Esto ofrece una gran flexibilidad al hacer coincidir microservicios con hardware específico cuando sea necesario, lo que permite implementaciones en hardware básico de bajo costo.

Aunque la naturaleza distribuida de los microservicios agrega complejidad a la arquitectura, uno de los mayores beneficios de los microservicios es la Escalabilidad. Con la aplicación general volviéndose modular, cada microservicio se puede escalar individualmente, ya sea de forma manual o automatizada a través del autoescalado bajo demanda.

Las actualizaciones y los procesos de aplicaciones de parcheo fluidos, son otros beneficios de la Arquitectura de Microservicios. Prácticamente no hay tiempo de inactividad ni interrupción del servicio para los clientes o usuarios porque las actualizaciones se implementan sin problemas, un servicio a la vez, en lugar de tener que volver a compilar, reconstruir y reiniciar una aplicación monolítica completa. Como resultado, las empresas pueden desarrollar e implementar nuevas funciones y actualizaciones mucho más rápido, con un enfoque ágil, en equipos separados que se centran en funciones independientes, lo que resulta más productivo y rentable.

Refactorización

Las empresas más nuevas y modernas poseen el conocimiento y la tecnología para crear aplicaciones nativas de La Nube que impulsan su negocio.

Desafortunadamente, ese no es el caso de las empresas ya establecidas, que ejecutan aplicaciones monolíticas heredadas. Algunos han intentado ejecutar monolitos como microservicios y, como era de esperar, no funcionó muy bien. Las lecciones aprendidas fueron que una aplicación multiproceso de tamaño monolítico no puede ejecutarse como un microservicio y que había que explorar otras opciones. El siguiente paso natural en el camino de la transición de monolito a microservicios fue la refactorización. Sin embargo, la migración de una aplicación de hace décadas hacia La Nube a través de la refactorización, plantea serios desafíos y la empresa enfrenta el dilema del enfoque de refactorización: un enfoque de "Big-bang" o una refactorización incremental.

Un enfoque llamado "Big-bang" centra todos los esfuerzos en la refactorización del monolito, posponiendo el desarrollo y la implementación de cualquier característica nueva, lo que esencialmente retrasa el progreso y posiblemente, en el proceso, incluso rompe el núcleo de la aplicación monolítica de negocio.

Un enfoque de refactorización incremental garantiza que se desarrollen e implementen nuevas características como microservicios modernos, las cuales pueden comunicarse con el monolito a través de APIs, sin agregar nada al código del monolito. Mientras tanto, las características se refactorizan fuera del monolito que se desvanece lentamente, mientras todas o la mayor parte de su funcionalidad se moderniza en microservicios. Este enfoque incremental ofrece una transición gradual de una Arquitecura Monolítica Heredada a una Arquitectura de Microservicios moderna, que permite la migración por fases de las características de la aplicación a La Nube.

Una vez que una empresa elige el camino de la refactorización, hay otras consideraciones en el proceso:
  • ¿Qué componentes comerciales separar del monolito para convertirse en microservicios distribuidos?
  • ¿Cómo desacoplar las bases de datos de la aplicación para separar la complejidad de los datos de la lógica de la aplicación?
  • ¿Cómo probar los nuevos microservicios y sus dependencias?
Estas son solo algunas de las decisiones que debe tomar una empresa que emprende una refactorización.

La fase de refactorización transforma lentamente el monolito en una aplicación nativa de La Nube, que aprovecha al máximo las características de ésta al estar codificanda en nuevos lenguajes de programación y aplicando patrones arquitectónicos modernos. A través de la refactorización, una aplicación monolítica heredada recibe una segunda oportunidad en la vida: vivir como un sistema modular adaptado para integrarse completamente con las herramientas y servicios de automatización de nube, que exige el ritmo rápido y cambiante de hoy.

Desafíos

El camino de refactorización de un monolito a los microservicios no es sencillo y presenta múltiples desafíos. Sólo para comenzar, no todos los monolitos son candidatos perfectos para la refactorización, mientras que algunos ni siquiera "sobreviven" a una fase de modernización de este tipo. Al decidir si un monolito es un posible candidato para la refactorización, hay muchas cuestiones posibles a tomar en cuenta.

Al considerar un sistema heredado basado en Mainframe, escrito en lenguajes de programación más antiguos como Cobol, RPG o Assembler, puede ser más económico simplemente reconstruirlo desde cero como una aplicación nativa de La Nube. Una aplicación heredada mal diseñada debe rediseñarse y reconstruirse desde cero siguiendo patrones arquitectónicos modernos para microservicios, e incluso Contenedores. Las aplicaciones estrechamente acopladas con almacenes de datos también son malos candidatos para la refactorización.

Una vez que el monolito sobrevivió a la fase de refactorización, el siguiente desafío es diseñar mecanismos o encontrar herramientas adecuadas para mantener vivos todos los módulos desacoplados, para garantizar la resiliencia de la aplicación en su conjunto.

Elegir tiempos de ejecución puede ser otro desafío. Si implementa muchos módulos en un solo servidor físico o virtual, es probable que diferentes bibliotecas y entornos de tiempo de ejecución entren en conflicto entre sí y causen errores y/o fallas. Esto obliga a la implementación de módulos individuales por servidor para separar sus dependencias, lo que no es una forma económica de administración de recursos ni una segregación real de bibliotecas y tiempos de ejecución, ya que cada servidor también tiene un sistema operativo subyacente que se ejecuta con sus bibliotecas, lo que consume recursos del servidor. En ocasiones, el sistema operativo consume más recursos que el módulo de aplicación en sí.

Una luz al final del túnel

Finalmente llegaron Los Contenedores de Aplicaciones (o Contenedores para abreviar), que proporcionan entornos de tiempo de ejecución ligeros y encapsulados para los módulos de aplicaciones. Los contenedores, desde su concepción original, prometían entornos de software consistentes para desarrolladores y evaluadores, desde el desarrollo hasta la producción. El amplio soporte de contenedores aseguró la portabilidad de las aplicaciones desde el hardware físico hasta las máquinas virtuales, pero esta vez con múltiples aplicaciones implementadas en el mismo servidor, cada una ejecutándose en sus propios entornos de ejecución aislados entre sí, evitando así conflictos, errores y fallas. Otras características de los entornos de aplicaciones en Contenedores son:
  • Mayor utilización del servidor
  • Escalabilidad de módulos individuales
  • Flexibilidad
  • Interoperabilidad
  • Fácil integración con herramientas de automatización
Casos de éxito

Aunque es un proceso desafiante, pasar de los monolitos a los microservicios es un viaje que tiene resultados gratificantes, especialmente una vez que una empresa comienza a ver crecimiento y éxito gracias a un sistema de aplicaciones refactorizado. A continuación, enumeramos solo algunas de las historias de éxito de empresas que aceptaron el desafío de modernizar sus aplicaciones comerciales monolíticas.

AppDirect: un proveedor de plataforma de comercio de un extremo a otro, que comenzó a partir de una aplicación monolítica compleja y, a través de la refactorización, pudo retener monolitos de funcionalidad limitada que recibieron muy pocos "commits", pero todas las características nuevas implementadas como microservicios en contenedores.

box: un proveedor de soluciones de almacenamiento en La Nube, comenzó a partir de una arquitectura monolítica compleja y, a través de la refactorización, pudo descomponerlo en microservicios.

Crowdfire: un proveedor de soluciones de gestión de contenido, dividió con éxito su monolito inicial en microservicios.

GolfNow: un proveedor de tecnología y servicios, decidió dividir sus monolitos en microservicios en contenedores.

Pinterest: un proveedor de servicios de redes sociales, inició el proceso de refactorización migrando primero su API monolítica.

Otras empresas, organizaciones e instituciones que han realizado de manera exitosa este viaje son: Adidas, Amadeus, AppDirect, Bode, Capital One, el CERN, IBM, Huawei, ING, Nokia, Nordsrom, Pintrest, Spotify, Yahoo, Wikimedia.

¿Su empresa, institución u organización aún cuenta con Aplicaciones Monolíticas?