Contenido


Más allá de clichés: Una breve historia de los patrones de microservicios

Explore el impacto de los últimos patrones de diseño de software en la creación de microservicios

Comments

Los microservicios son la nueva cosa candente en el desarrollo de aplicaciones comerciales. El término microservicio ha reemplazado a Agile, DevOps y RESTful como la nueva palabra de moda que todos los currículos y conferencias destacan ahora. Pero los microservicios son algo más que una tendencia pasajera. De hecho, son la evolución de todos estos conceptos previos y un abordaje que ha comenzado a mostrar la promesa de superar una serie de viejos problemas en el desarrollo de aplicaciones. . Junto con la lectura de este artículo, los invito a ver MicroservicesTV Episodio 13 y Episodio 14 (ver a continuación) para obtener una sólida comprensión de cómo, dónde y por qué los microservicios evolucionaron.

Iniciando por el principio

Para comprender esta evolución, debemos ir atrás en el tiempo para examinar qué son los microservicios, lo que han sustituido, y por qué se volvieron necesarios. Empecemos a principios de la década de los 80s con la introducción de la primera tecnología importante de distribución de sistemas: Llamadas a Procedimiento Remoto (RPC). RPC fue el concepto detrás del ONC RPC de Sun Microsystems, así como la idea básica detrás de DCE (1988) y CORBA (1991).

En cada una de estas tecnologías, la idea básica era hacer llamadas remotas transparentes para desarrolladores. La promesa era que si los desarrolladores no tenían que preocuparse de si las llamadas o métodos de procedimiento que invocaban eran locales o remotos, entonces ellos podrían construir sistemas de cruce de máquinas mayores, que podrían evitar problemas de escalabilidad de procesamiento y memoria que afectaban a los sistemas de la época. (¡Recuerde que los procesadores más comunes en ese momento eran los procesadores de 16 bits con un espacio de direcciones de 64K!))

Conforme los procesadores mejoraron y los espacios de direcciones locales fueron mayores, esta cuestión se volvió menos importante. Lo que es más, el primer conjunto de implementaciones grandes de DCE y CORBA enseñó a los arquitectos una observación importante sobre la computación distribuida:

Tan sólo porque algo puede estar distribuido, no significa que debería estar distribuido.

Una vez que los grandes espacios de memoria se convirtieron en algo común, se hizo evidente que las malas decisiones sobre la distribución de sus métodos a lo largo de las máquinas, podría tener consecuencias nefastas sobre el rendimiento del sistema. El intento anterior de distribuir todo generó muchos sistemas con interfaces de mucha charla — incluso hasta el punto de distribuir los captadores y establecedores de variables en los lenguajes orientados hacia objetos. En un sistema como este, la sobrecarga de red superó ampliamente las ventajas de la distribución.

Esto nos llevó a nuestro primer patrón, que tenía la intención de abordar la observación de arriba —y que fue un patrón que descubrí independientemente con John Crupi y Martin Fowler. En cada caso, iniciamos con el libro de Erich Gamma Design Patterns: Elements of Reusable Object Oriented Design (Patrones de Diseño: Elementos de Diseño Orientado Hacia Objeto Reutilizable) y nos dimos cuenta del patrón de Fachada. El patrón de Fachada trataba acerca de encapsular las interfaces no estructuradas de un sistema grande dentro de una única interfaz más estructurada para reducir la "charla" En otras palabras, tenía que ver con la reducción de la muestra representativa de la interfaz del sistema. El abordaje de Fachada de sesión que hemos desarrollado, aplicó este patrón a sistemas distribuidos mediante la identificación de las principales interfaces de alto grado de todo un subsistema y exponer únicamente las de distribución.

Implementamos nuestras primeras Fachadas de Sesión con la tecnología Enterprise JavaBeans (EJB), que aunque está bien si sólo estaban trabajando en Java, era complicada, difícil de depurar, y no es interoperable con otros idiomas o incluso con productos de otros proveedores. La falta de interoperabilidad llevó directamente al esfuerzo siguiente de principios a mediados de la década de los 2000: lo que se conoce como Arquitectura Orientada a Servicios (SOA). Aunque SOA no comenzó con una grandiosa terminología. Originalmente comenzó como un esfuerzo para "hacer la cosa más fácil que pudiera funcionar" llamado Protocolo de Acceso de Objeto Sencillo (SOAP), originalmente lanzado por Microsoft en 1999.

En esencia, SOAP no era nada más que una manera de invocar métodos de objetos a través de HTTP. Aprovechaba dos artefactos del mundo de la computación de a principios de los años 2000: el creciente soporte para HTTP en las redes corporativas, y el hecho de que este soporte incluía mecanismos de registro cronológico y depuración de llamadas de red basadas en texto.

Los primeros destellos del esfuerzo alrededor de SOAP eran útiles porque rápidamente establecieron que fácilmente puede interoperar entre sistemas implantados en muchos idiomas diferentes y en diferentes plataformas. Pero donde SOA como un todo falló, fue en ir más allá de este principio sencillo, ya que añadía capas y capas de conceptos adicionales más allá de la simple invocación de método: Manejo de excepciones, soporte de transacciones, seguridad y firmas digitales fueron añadidos a algo que algunos ya consideraban un protocolo complicado. Esto llevó a la siguiente importante observación:

Intentar hacer que una llamada distribuida actúe como una llamada local siempre termina en tragedia.

La industria como un todo, lentamente comenzó a girar en torno de un rechazo del procedimiento, conceptos en capas inherentes a SOAP y los estándares WS-*. En lugar de eso, lo que se hizo más generalizado fue la adopción de Representational State Transfer (REST), que se remontaba a la tesis de doctorado de Roy Fielding en 2000. El principio fundacional de REST es terriblemente sencillo: Tratar a HTTP como HTTP. En lugar de que la capa de procedimiento llame a la semántica a través de HTTP, REST trata los verbos HTTP de la forma en que se especifica en términos de crear, leer, eliminar y actualizar la semántica. También esboza un método para especificar los nombres de entidad única a través de otro principio aceptado de la web: el URI.

Al mismo tiempo, la industria también se trasladaba hacia el rechazo de otro legado de la plataforma Java, el mundo de Enterprise Edition (JEE) y SOA: la gran granja de servidores de aplicaciones. Desde que Enterprise Java fue introducido en 1999 (extrañamente como la versión 1.2), hubo una tensión permanente entre los propietarios de las aplicaciones y los administradores de las aplicaciones.

Cuando se introdujo JEE, muchas corporaciones se trasladaron hacia la adopción de la noción de un servidor de aplicaciones como un host para diferentes aplicaciones porque era similar a los actuales modelos de sistema principal. Un solo grupo de operaciones podría controlar, monitorear y mantener una "granja" de servidores de aplicaciones idénticos de Oracle o de IBM y desplegaría diferentes aplicaciones departamentales en esa granja. Esta estandarización y consistencia fue magnífica para el equipo de operaciones y para reducir los costos operativos en general. Pero esto creó conflictos con los desarrolladores de aplicaciones, debido a que los entornos de prueba y desarrollo eran grandes, difícil de crear, y requerían la participación del equipo de operaciones. Esto a menudo significaba que podía tomar meses para que se crearan los nuevos entornos, ralentizando proyectos e incrementando sus costos de desarrollo. Lo que es más, debido a que estos entornos estaban fuera del control del equipo, a menudo había incoherencias entre las versiones de servidor de aplicaciones, los niveles de parches, los datos de aplicaciones y las instalaciones de software entre entornos.

Lo que los desarrolladores preferían eran plataformas de aplicaciones menores y ligeras, — normalmente servidores de aplicaciones de código abierto como Tomcat o Glassfish. Al mismo tiempo, la complejidad del JEE estaba siendo rechazada en favor de la supuesta simplicidad de la plataforma Spring en la medida en que las técnicas como Control de Inversión e Inyección de Dependencia se volvieron comunes. Las ganancias de esto consistieron en que los equipos de desarrollo descubrieron que la obtención de la capacidad para generar e implementar sistemáticamente sus propias aplicaciones, en entornos de desarrollo, prueba y producción que estaban lo más cercanos unos de los otros, no sólo era más rápida, sino menos propensa al error ya que se eliminaron clases enteras de errores derivados de incongruencias de entornos. Esto condujo a la siguiente observación:

Siempre que sea posible, sus programas y sus entornos de tiempo de ejecución deben estar totalmente autocontenidos.

Estas tres observaciones están en el corazón de lo que Fowler describe como de lo que tratan los microservicios. Uno de los principios del diseño de microservicios de Fowler, es que los microservicios "están organizados en torno a las capacidades de negocios". Eso se deriva directamente del descubrimiento de que sólo porque usted puede distribuir algo no significa que lo debe distribuir. Todo el concepto del patrón de Fachada en sus diversas encarnaciones, tiene que ver con la definición de una API externa específica para un sistema o subsistema. El subtexto de esto fue que esta API estaría orientada hacia los negocios. Fowler hace que ese contexto sea explícito.

Frecuentemente, la comprensión de lo que esto significa es un obstáculo para algunos equipos de desarrollo, — ellos simplemente no son utilizados para diseñar en términos de interfaces de negocios y podrían encontrarse rápidamente pasando a ser interfaces técnicas (como Inicio de Sesión o Registro Cronológico). En estos casos, lo que muchos equipos han descubierto como aplicables, son varios patrones del libro de Eric Evans, Domain Driven Design (Diseño Impulsado por Dominio). En particular, su Entidad y Patrones Agregados son útiles en la identificación de conceptos de negocios específicos que se correlacionan directamente a microservicios. Asimismo, su patrón de Servicios ofrece también un modo de operaciones de correlación que no corresponden a una sola entidad o agregado en el abordaje basado en Entidad que usted necesita para microservicios.

Del mismo modo, la regla de Fowler de emplear "puntos finales inteligentes y conductos que no llevan a ningún lugar" nace de la experiencia de que los equipos que utilizan EJBs, SOAP y otras tecnologías de distribución compleja han llegado a la observación de que intentar hacer que un sistema distribuido parezca siempre local, siempre termina en tragedia. Por último, Fowler dicta en relación a la Gobernanza Descentralizada y la Gestión Descentralizada de Datos que provienen del laborioso descubrimiento de que sus programas y entornos de tiempo de ejecución deben estar autocontenidos.

¿Dónde nos deja todo esto?

Fowler, Adrian Cockcroft, y otros han hecho un caso convincente de por qué los equipos de desarrollo deben adoptar los microservicios. Pero si nos fijamos en la forma en que todas las lecciones que llevaron a la arquitectura de microservicios fueron adquiridas, podemos sacar una conclusión que difiere un poco de la historia que acabo de contar, centrada en el desarrollador. En particular, tiene que observar la realidad de hacer que los microservicios funcionen en un mundo corporativo de aplicaciones existentes, y también darse cuenta de la importancia que la arquitectura de microservicios pone en el lado de operaciones de DevOps.

Vivir en el mundo corporativo

La arquitectura microservicios comenzó a obtener atención después de que una serie de historias de éxito fueron publicadas por compañías como Netflix, Gilt.com y Amazon. Sin embargo, todas estas compañías, y muchos de los otros éxitos de microservicios, comparten algo en común, — todos provienen de compañías Web que estaban desarrollando nuevas aplicaciones o que no tenían una base de código heredado sustanciales para reemplazar. Cuando la corporación tradicional adopta microservicios, uno de los temas con los que se deparan después de que las primeras aplicaciones nuevas son seleccionadas para probar los microservicios, es que algunos de los postulados de la arquitectura de microservicios, particularmente la "Gestión de Datos Descentralizados" y la "Gobernanza Descentralizada", son difíciles de poner en práctica cuando usted deben refactorizar un gran aplicación monolítica.

Pero afortunadamente, un abordaje para este problema ha estado disponible durante varios años bajo la forma de un patrón que Martin Fowler documentó originalmente en 2004, varios años antes de su trabajo de microservicios. Su concepto es llamado el "patrón de aplicación estrangulador", y tiene la intención de abordar el hecho de que casi nunca se vive realmente en terreno virgen. Los programas que necesitan más microservicios son aquellos que son los más grandes y más desagradables en la Web, pero de nuevo, el aprovechar las ventajas de la arquitectura Web nos puede proporcionar una estrategia para la gestión de la refactorización que se necesita.

La aplicación estranguladora es un concepto muy simple que se basa en la analogía de una enredadera que estrangula el árbol que envuelve. La idea es que usted emplea la estructura de la aplicación Web, — el hecho es que se construye a partir de URIs individuales que correlacionan la funcionalidad a diferentes aspectos de un dominio de negocios — para dividir una aplicación en diferentes dominios funcionales y reemplazar esos dominios con una nueva implementación basada en microservicios un dominio a la vez. Estos dos aspectos forman aplicaciones separadas que viven lado a lado en el mismo espacio URI. A lo largo del tiempo, la nueva aplicación refactorizada estrangula o reemplaza a la aplicación original, hasta que finalmente usted es capaz de apagar la aplicación monolítica.

Pero ese no es el único patrón que hemos descubierto como útil para hacer que el abordaje de microservicios funcione en el mundo corporativo. Otro aspecto importante es que, en muchos casos, un equipo de desarrollo no llega a tener control descentralizado de sus datos. Este es el motivo de un patrón que llamamos Microservicio Adaptador, que es una extensión del patrón original del Adaptador de Patrones de Diseño por Erich Gamma y otros.

En un Microservicio de Adpatador, usted adapta entre dos diferentes APIs. La primera es una API orientada hacia negocios, que está construida usando técnicas de mensajería RESTful o ligeras y diseñada empleando las mismas técnicas impulsadas por dominio que un microservicio tradicional. Pero la segunda API a la que se adapta es una API heredada o tradicional basada en servicio SOAP WS-*. Los puristas podrían oponerse a este abordaje y tratar de insistir en que si usted no adopta datos descentralizados, entonces usted no está utilizando microservicios. Sin embargo, los datos corporativos existen por un motivo, y frecuentemente hay motivos distintos a la inercia organizacional. Podría ser que exista un número significativo de aplicaciones heredadas que todavía necesiten el acceso a esos datos bajo su forma actual que no pueden ser fácilmente adaptadas a una nueva API, o quizás el mismo peso de los datos (a menudo medido en cientos de terabytes o petabytes) impide su migración hacia una nueva forma que sea propiedad de un único servicio.

Colocando las operaciones de nuevo en DevOps

Otro aspecto importante de los microservicios aborda el lado de operaciones del conjunto de prácticas conocidas como DevOps. Esto tiene sus raíces en una serie de patrones que fueron originalmente desarrollados para la gestión de aplicaciones convencionales. Fowler destacó la importancia de esto en su documento original sobre microservicios, donde dijo que es necesario adaptar la automatización de la infraestructura como parte de un proceso de DevOps construido sobre Entrega Continua e Integración Continua. Sin embargo, la necesidad de esto no siempre es evidente para los equipos que comienzan a adoptar microservicios a pequeña escala. El problema es que mientras que el uso de microservicios facilita cambiar e implementar un único servicio rápidamente, también hace que el esfuerzo global de gestión y mantenimiento de un conjunto de servicios sea mayor de lo que sería en una aplicación monolítica correspondiente.

Por ejemplo, este es un motivo por el que muchas infraestructuras comunes como la infraestructura de microservicios de Netflix y Amalgam8, adaptan el patrón de Registro de Servicio: Al evitar puntos finales de microservicios específicos de codificación difícil en su código, se puede cambiar no sólo la implementación de los microservicios hacia abajo, sino que también se puede elegir la ubicación del servicio para variar en las distintas etapas de su canal de DevOps. Sin servicio de registro, su aplicación rápidamente se volvería torpe conforme los cambios al código se comiencen a propagar hacia arriba a lo largo de una cadena de llamada de microservicios.

Esta idea de lograr un mayor aislamiento y al mismo tiempo hacer posible más fácilmente depurar microservicios, está en el centro de varios de los patrones DevOps que hemos identificado, particularmente ID de Correlación y Agregador de Registro. El patrón de ID de Correlación patrón fue identificado y documentado en una forma específica en el libro de Gregor Hohpe, Enterprise Integration Patterns (Patrones de Integración Empresarial), pero ahora hemos observado el concepto generalizado en proyectos como OpenTracing, que permite rastrear la propagación a través de una serie de microservicios que están escritos en varios idiomas diferentes. El Agregador de Registro es un nuevo modelo que ha sido implementado en diversos productos de código abierto y comerciales (tales como Cloud Foundry y la pila de código abierto); se complementa con IDs de correlación permitiendo que los registros de diferentes microservicios sean agregados en un único repositorio de búsqueda. Juntos, permiten una eficiente y comprensible depuración de microservicios, independientemente del número de servicios o de la profundidad de cada pila de llamadas.

Finalmente, otro aspecto de DevOps, que es un puente fundamental entre los dos, es lo que Fowler señala en su artículo como: la importancia de diseñar para las fallas. En particular, la infraestructura Hystrix de Netflix, se ha convertido en una parte importante de muchas implementaciones de microservicios debido a su implementación del patrón de Disyuntor. El Disyuntor de documentó por primera vez en el libro de Michael Nygard de 2007 Release It! (¡Libérelo!). Con el Disyuntor, puede evitar la pérdida de tiempo manejando fallas si ya sabe lo que está ocurriendo, y usted puede manejar esto plantando una sección de código de Disyuntor en las llamadas de servicio hacia arriba, que puede detectar cuando un servicio hacia abajo está fallando y evitar intentar llamarlo. La ventaja de esto es que cada llamada "falla rápido", y puede proporcionar una mejor experiencia general a los usuarios y evitar la mala gestión de recursos como hilos y agrupaciones de conexión cuando sabe que las llamadas hacia abajo están destinadas a fallar.

Este tipo de gestión de recursos se utiliza para ser la única área del lado de operaciones de DevOps, pero la arquitectura de microservicios reúne más eficazmente los dos lados, ya que ambos trabajan para hacer que las aplicaciones sean más confiables, eficientes y flexibles.

¿Cuál es el próximo paso?

En este artículo y en los videos que lo acompañan, hemos explorado los antecedentes históricos de los microservicios y examinado cómo surgió la arquitectura de microservicios. También discutimos qué tipo de patrones necesita seguir para aplicar con éxito microservicios en el mundo corporativo, y qué tipo de desafíos pueden surgir al aplicar la arquitectura de microservicios.


Recursos para Descargar


Temas relacionados


Comentarios

Inicie Sesión o Regístrese para agregar comentarios.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Cloud computing
ArticleID=1041704
ArticleTitle=Más allá de clichés: Una breve historia de los patrones de microservicios
publish-date=12282016