{"id":35906,"date":"2019-10-31T22:07:29","date_gmt":"2019-10-31T19:07:29","guid":{"rendered":"https:\/\/prohoster.info\/blog\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika\/"},"modified":"2019-10-31T22:07:29","modified_gmt":"2019-10-31T19:07:29","slug":"perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","title":{"rendered":"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>En este art\u00edculo, hablar\u00e9 sobre c\u00f3mo el proyecto en el que trabajo ha evolucionado de un gran monolito a un conjunto de microservicios.<\/p>\n<p>El proyecto comenz\u00f3 su historia hace bastante tiempo, a principios de 2000. Las primeras versiones fueron escritas en Visual Basic 6. Con el tiempo, qued\u00f3 claro que el desarrollo en este lenguaje ser\u00eda dif\u00edcil de mantener en el futuro, dado que el IDE y el propio lenguaje evolucionaban lentamente. A finales de la d\u00e9cada de 2000, se decidi\u00f3 migrar a un C# m\u00e1s prometedor. La nueva versi\u00f3n se desarroll\u00f3 en paralelo con las mejoras de la antigua, y poco a poco, se fueron integrando m\u00e1s c\u00f3digos en .NET. El backend en C# inicialmente se orient\u00f3 a una arquitectura de servicios, sin embargo, durante el desarrollo se utilizaron bibliotecas comunes con l\u00f3gica, y los servicios se ejecutaban en un \u00fanico proceso. As\u00ed, se obtuvo una aplicaci\u00f3n que nosotros denominamos 'monolito de servicios'. <\/p>\n<p>Una de las pocas ventajas de esta combinaci\u00f3n era la capacidad para que los servicios se invocaran entre s\u00ed a trav\u00e9s de una API externa. Hab\u00eda evidentes presunciones para pasar a una arquitectura de servicios m\u00e1s adecuada, y a la larga, a una arquitectura de microservicios. <\/p>\n<p>Comenzamos nuestro trabajo de descomposici\u00f3n alrededor de 2015. A\u00fan no hemos alcanzado un estado ideal; quedan partes del gran proyecto que ya son dif\u00edciles de considerar monolitos, pero tampoco son realmente microservicios. Sin embargo, el progreso ha sido significativo. <br \/>\nSobre esto hablar\u00e9 en el art\u00edculo.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/132bb4ea6b9dbcdd202ee090f2b86289.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Contenido<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#1\"> Arquitectura y problemas de la soluci\u00f3n existente<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#2\">Expectativas sobre los microservicios<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#3\">Problemas de la transici\u00f3n<\/a><\/noindex><\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"#4\">C\u00f3mo pasar de un monolito a microservicios<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#5\">Primer m\u00e9todo<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#6\">Segundo m\u00e9todo<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#7\">Tercer m\u00e9todo<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#8\">Cuarto m\u00e9todo<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#9\">Trabajo con la base de datos<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#10\">Separaci\u00f3n de las tablas existentes<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#11\">Separaci\u00f3n con reestructuraci\u00f3n<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#12\">Trabajo con el c\u00f3digo fuente<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#13\">Problemas de infraestructura<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#16\">Instalaci\u00f3n manual en entornos<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#14\">Registro separado<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#15\">Pruebas y depuraci\u00f3n de servicios relacionados<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><noindex><a rel=\"nofollow\" name=\"1\"><\/a><\/noindex><b><\/p>\n<h3>Arquitectura y problemas de la soluci\u00f3n existente<\/h3>\n<p><\/b><br \/>\nInicialmente, la arquitectura se ve\u00eda de la siguiente manera: la interfaz de usuario era una aplicaci\u00f3n independiente, la parte monol\u00edtica estaba escrita en Visual Basic 6, y la aplicaci\u00f3n en .NET consist\u00eda en un conjunto de servicios relacionados que trabajaban con una base de datos bastante grande.<\/p>\n<p><b>Desventajas de la soluci\u00f3n anterior<\/b><\/p>\n<p><u>Punto \u00fanico de fallo<\/u><br \/>\nTen\u00edamos un punto \u00fanico de fallo: la aplicaci\u00f3n en .NET se ejecutaba en un solo proceso. Si hab\u00eda un fallo en alguno de los m\u00f3dulos, la aplicaci\u00f3n fallaba completamente y hab\u00eda que reiniciarla. Dado que automatizamos una gran cantidad de procesos para diferentes usuarios, debido a un fallo en uno de ellos, todos no pod\u00edan trabajar durante un tiempo. Y en caso de un error de programaci\u00f3n, la reserva no ayudaba. <\/p>\n<p><u>Cola de mejoras<\/u><br \/>\nEsta deficiencia es m\u00e1s bien organizativa. En nuestra aplicaci\u00f3n hay muchos clientes, y todos quieren mejorarla lo antes posible. Anteriormente, era imposible hacerlo en paralelo, y todos los clientes se pon\u00edan en cola. Este proceso generaba descontento en el negocio, ya que necesitaban demostrar que su tarea ten\u00eda valor. Y el equipo de desarrollo gastaba tiempo organizando esta cola. Esto consum\u00eda mucho tiempo y esfuerzo, y el producto no pod\u00eda cambiar tan r\u00e1pido como ellos deseaban.<\/p>\n<p><u>Uso sub\u00f3ptimo de recursos<\/u><br \/>\nAl alojar servicios en un solo proceso, siempre copi\u00e1bamos completamente la configuraci\u00f3n de servidor a servidor. Quer\u00edamos alojar los servicios m\u00e1s demandantes por separado, para no desperdiciar recursos y tener un control m\u00e1s flexible sobre nuestro esquema de despliegue.<\/p>\n<p><u>Dificultad para implementar tecnolog\u00edas modernas<\/u><br \/>\nProblema conocido para todos los desarrolladores: hay ganas de implementar tecnolog\u00edas modernas en el proyecto, pero no hay posibilidades. Con una gran soluci\u00f3n monol\u00edtica, cualquier actualizaci\u00f3n de la biblioteca actual, sin mencionar la transici\u00f3n a una nueva, se convierte en una tarea bastante no trivial. Es necesario convencer durante mucho tiempo al l\u00edder de equipo de que esto traer\u00e1 m\u00e1s beneficios que nervios gastados. <\/p>\n<p><u>Complejidad de la entrega de cambios<\/u><br \/>\nEste fue el problema m\u00e1s serio: lanz\u00e1bamos versiones cada dos meses. <br \/>\nCada lanzamiento se convert\u00eda en una verdadera cat\u00e1strofe para el banco, a pesar de las pruebas y los esfuerzos de los desarrolladores. El negocio entend\u00eda que no tendr\u00eda parte de la funcionalidad funcionando al inicio de la semana. Y los desarrolladores sab\u00edan que les esperaba una semana de incidentes serios. <br \/>\nTodos ten\u00edan el deseo de cambiar la situaci\u00f3n. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"2\"><\/a><\/noindex><b><\/p>\n<h3>Expectativas sobre los microservicios<\/h3>\n<p><\/b><br \/>\n<u>Entrega de componentes seg\u00fan disponibilidad. <\/u>Entrega de componentes a medida que est\u00e1n listos gracias a la descomposici\u00f3n de la soluci\u00f3n y la separaci\u00f3n de diferentes procesos.<\/p>\n<p><u>Peque\u00f1os equipos de productos.<\/u> Esto es importante porque es dif\u00edcil de gestionar un gran equipo que trabaja en un antiguo monolito. Tal equipo se ve obligado a seguir un proceso estricto, mientras que se desea m\u00e1s creatividad e independencia. Esto solo pod\u00edan permitirse equipos peque\u00f1os.<\/p>\n<p><u>Aislamiento de servicios en procesos separados.<\/u> Idealmente, se deber\u00eda aislar en contenedores, pero un gran n\u00famero de servicios escritos en .NET Framework solo se ejecutan en Windows. Ahora est\u00e1n surgiendo servicios en .NET Core, aunque todav\u00eda son pocos.<\/p>\n<p><u>Flexibilidad de despliegue.<\/u> Nos gustar\u00eda combinar servicios seg\u00fan nuestras necesidades y no de la manera que impone el c\u00f3digo.<\/p>\n<p><u>Uso de nuevas tecnolog\u00edas.<\/u> Esto es interesante para cualquier programador.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"3\"><\/a><\/noindex><b><\/p>\n<h3>Problemas de la transici\u00f3n<\/h3>\n<p><\/b><br \/>\nPor supuesto, si fuera sencillo dividir un monolito en microservicios, no se hablar\u00eda de ello en conferencias ni se escribir\u00edan art\u00edculos. Este proceso tiene muchos escollos, describir\u00e9 los principales que nos dificultaron.<\/p>\n<p><b>El primer problema<\/b> es t\u00edpico de la mayor\u00eda de los monolitos: la coherencia de la l\u00f3gica de negocio. Cuando escribimos un monolito, deseamos reutilizar nuestras clases para no escribir c\u00f3digo innecesario. Pero al pasar a microservicios, esto se convierte en un problema: todo el c\u00f3digo est\u00e1 bastante r\u00edgidamente vinculado y es dif\u00edcil dividir los servicios.<\/p>\n<p>En el momento de comenzar el trabajo, hab\u00eda m\u00e1s de 500 proyectos en el repositorio y m\u00e1s de 700 mil l\u00edneas de c\u00f3digo. Es una soluci\u00f3n bastante grande y <b>el segundo problema<\/b>No era posible simplemente dividirlo en microservicios.<\/p>\n<p><b>El tercer problema<\/b> es la falta de la infraestructura necesaria. De hecho, nos dedicamos a copiar manualmente el c\u00f3digo fuente en los servidores.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"4\"><\/a><\/noindex><b><\/p>\n<h3>C\u00f3mo pasar de un monolito a microservicios<\/h3>\n<p><\/b><br \/>\n<u>Identificaci\u00f3n de microservicios<\/u><\/p>\n<p>En primer lugar, definimos de inmediato que la separaci\u00f3n de microservicios es un proceso iterativo. Siempre se nos exigi\u00f3 que simult\u00e1neamente desarroll\u00e1ramos tareas comerciales. C\u00f3mo lo vamos a llevar a cabo t\u00e9cnicamente es nuestro problema. Por lo tanto, estuvimos preparados para un proceso iterativo. De otra manera no funcionar\u00e1, si tienes una gran aplicaci\u00f3n que no est\u00e1 lista desde el principio para ser reescrita.<\/p>\n<p>\u00bfQu\u00e9 m\u00e9todos utilizamos para identificar microservicios?<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"5\"><\/a><\/noindex><b>Primer m\u00e9todo <\/b>\u2014 extraer m\u00f3dulos existentes como servicios. En este sentido, tuvimos suerte: ya exist\u00edan servicios configurados que funcionaban con el protocolo WCF. Estaban distribuidos en ensamblajes separados. Los trasladamos individualmente, a\u00f1adiendo un peque\u00f1o m\u00f3dulo de inicio a cada ensamblaje. Este fue escrito con la magn\u00edfica biblioteca Topshelf, que permite ejecutar la aplicaci\u00f3n tanto como servicio como consola. Esto es conveniente para la depuraci\u00f3n, ya que no se requieren proyectos adicionales en la soluci\u00f3n.<\/p>\n<p>Los servicios estaban conectados por l\u00f3gica de negocio, ya que utilizaban ensamblajes comunes y trabajaban con una base de datos compartida. Era dif\u00edcil llamarlos micorservicios en el sentido m\u00e1s puro. Sin embargo, pod\u00edamos presentar estos servicios por separado, en diferentes procesos. Esto ya permit\u00eda reducir la influencia que ten\u00edan unos sobre otros, disminuyendo el problema con el desarrollo paralelo y el punto \u00fanico de falla.<\/p>\n<p>El ensamblaje con el host es solo una l\u00ednea de c\u00f3digo en la clase Program. Ocultamos el trabajo con Topshelf en una clase auxiliar.<\/p>\n<pre><code class=\"plaintext\">namespace RBA.Services.Accounts.Host\n{\n   internal class Program\n   {\n      private static void Main(string[] args)\n      {\n        HostRunner.Run(\"RBA.Services.Accounts.Host\");\n\n       }\n    }\n}\n<\/code><\/pre>\n<p>\n<noindex><a rel=\"nofollow\" name=\"6\"><\/a><\/noindex><b>La segunda forma de destacar microservicios:<\/b> crearlos para resolver nuevas tareas. Si el monolito no crece, eso ya es excelente, significa que estamos avanzando en la direcci\u00f3n correcta. Para resolver nuevas tareas, tratamos de crear servicios separados. Siempre que fuera posible, creamos servicios m\u00e1s \"can\u00f3nicos\", que controlan completamente su modelo de datos y tienen su propia base de datos. <\/p>\n<p>Al igual que muchos, comenzamos con servicios de autenticaci\u00f3n y autorizaci\u00f3n. Son perfectos para esto. Son independientes, por lo general tienen un modelo de datos separada. No interact\u00faan con el monolito, solo este se dirige a ellos para resolver ciertas tareas. En estos servicios podemos comenzar la transici\u00f3n a la nueva arquitectura, depurar la infraestructura en ellos, probar enfoques relacionados con bibliotecas de red, etc. En nuestra organizaci\u00f3n, no hay equipos que no puedan configurar un servicio de autenticaci\u00f3n. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"7\"><\/a><\/noindex><b>La tercera forma de destacar microservicios<\/b>, que utilizamos, es un poco espec\u00edfico para nosotros. Se trata de separar la l\u00f3gica del negocio de la capa de UI. Nuestra aplicaci\u00f3n principal de UI es de escritorio, y tanto esta como el backend est\u00e1n escritas en C#. Los desarrolladores cometen errores de forma peri\u00f3dica y colocan en la UI partes de l\u00f3gica que deber\u00edan existir en el backend y ser reutilizables. <\/p>\n<p>Si miramos un ejemplo real del c\u00f3digo de la parte de UI, se puede ver que la mayor parte de esta soluci\u00f3n contiene verdadera l\u00f3gica de negocio, que es \u00fatil en otros procesos, no solo para construir formularios de UI. <\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/74c7b90ff94b343816ab3ac2fa0673c6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLa verdadera l\u00f3gica de UI est\u00e1 solo en las \u00faltimas l\u00edneas. La trasladamos al servidor para poder reutilizarla, lo que reduce la UI y nos permite lograr una arquitectura correcta.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"8\"><\/a><\/noindex><b>La cuarta y m\u00e1s importante forma de destacar microservicios<\/b>, que permite reducir el monolito, es la extracci\u00f3n de servicios existentes con reestructuraci\u00f3n. Cuando extraemos m\u00f3dulos existentes tal como est\u00e1n, el resultado no siempre es satisfactorio para los desarrolladores, y el proceso de negocio puede haber quedado obsoleto desde que se cre\u00f3 la funcionalidad. Gracias a la refactorizaci\u00f3n, podemos mantener un nuevo proceso de negocio, porque los requisitos cambian constantemente. Podemos mejorar el c\u00f3digo fuente, eliminar defectos conocidos y crear un modelo de datos de mayor calidad. Se acumulan muchas ventajas.<\/p>\n<p>La separaci\u00f3n de servicios con reestructuraci\u00f3n est\u00e1 inextricablemente relacionada con el concepto de contexto limitado. Este concepto proviene del dise\u00f1o orientado a objetos. Se refiere a un \u00e1rea del modelo de dominio donde todos los t\u00e9rminos de un lenguaje \u00fanico est\u00e1n definidos de manera un\u00edvoca. Tomemos como ejemplo el contexto de seguros y cuentas. Tenemos una aplicaci\u00f3n monol\u00edtica, y es necesario trabajar en los seguros con la cuenta. Esperamos que el desarrollador encuentre en otro ensamblaje la clase existente 'Cuenta', haga referencia a ella desde la clase 'Seguro', y obtendremos c\u00f3digo funcional. Se cumplir\u00e1 el principio DRY, y la tarea se completar\u00e1 m\u00e1s r\u00e1pido gracias al uso del c\u00f3digo existente.<\/p>\n<p>En consecuencia, resulta que los contextos de las cuentas y los seguros est\u00e1n relacionados. Cuando surjan nuevos requisitos, esta relaci\u00f3n obstaculizar\u00e1 el desarrollo, aumentando la complejidad de una l\u00f3gica de negocio que ya es complicada. Para abordar este problema, es necesario encontrar en el c\u00f3digo las fronteras entre contextos y eliminar sus violaciones. Por ejemplo, para los contextos de seguros, es probable que un n\u00famero de cuenta del Banco Central de 20 d\u00edgitos y la fecha de apertura de la cuenta sean suficientes. <\/p>\n<p>Para separar estos contextos limitados entre s\u00ed y comenzar el proceso de extracci\u00f3n de microservicios de una soluci\u00f3n monol\u00edtica, utilizamos un enfoque como la creaci\u00f3n de API externas dentro de la aplicaci\u00f3n. Si sab\u00edamos que alg\u00fan m\u00f3dulo deber\u00eda convertirse en un microservicio, de alguna manera transformarse dentro del proceso, inmediatamente hac\u00edamos llamadas a la l\u00f3gica que pertenece a otro contexto limitado a trav\u00e9s de llamadas externas. Por ejemplo, a trav\u00e9s de REST o WCF.<\/p>\n<p>Nosotros decidimos firmemente que no evitar\u00edamos el c\u00f3digo que requerir\u00eda realizar transacciones distribuidas. En nuestro caso, result\u00f3 bastante f\u00e1cil seguir esta regla. Hasta ahora, no hemos tenido situaciones en las que realmente se necesitaran transacciones distribuidas estrictas; la consistencia final entre los m\u00f3dulos ha sido m\u00e1s que suficiente.<\/p>\n<p>Consideremos un ejemplo concreto. Tenemos el concepto de orquestador: un canal que procesa la entidad \"solicitud\". Crea al cliente, la cuenta y la tarjeta bancaria uno tras otro. Si el cliente y la cuenta se crean con \u00e9xito, pero la creaci\u00f3n de la tarjeta falla, la solicitud no cambia a estado \"exitoso\" y permanece en estado \"tarjeta no creada\". En el futuro, una actividad en segundo plano la recoger\u00e1 y finalizar\u00e1. El sistema permanece en un estado de inconsistencia durante alg\u00fan tiempo, pero en general, estamos satisfechos con ello.<\/p>\n<p>En caso de que surja una situaci\u00f3n en la que sea necesario guardar de manera coherente parte de los datos, es probable que optemos por consolidar el servicio para manejar esto en un solo proceso. <\/p>\n<p>Consideremos un ejemplo de extracci\u00f3n de un microservicio. \u00bfC\u00f3mo se puede llevarlo de manera relativamente segura a producci\u00f3n? En este ejemplo, tenemos una parte separada del sistema: el m\u00f3dulo de servicios de n\u00f3mina, uno de cuyos fragmentos de c\u00f3digo nos gustar\u00eda convertir en microservicio.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/346af271b0c3f99897d330e56f713f18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPrimero creamos un microservicio, reescribiendo el c\u00f3digo. Mejoramos algunos aspectos que no nos satisfac\u00edan. Implementamos nuevos requisitos comerciales del cliente. Agregamos un API Gateway en la conexi\u00f3n entre la interfaz de usuario y el backend, que proporcionar\u00e1 el paso de llamadas. <\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/bec8d68f20f3ec53af0cef225a51c2b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA continuaci\u00f3n, lanzamos esta configuraci\u00f3n en producci\u00f3n, pero en estado piloto. La mayor\u00eda de nuestros usuarios todav\u00eda trabaja con los antiguos procesos comerciales. Para los nuevos usuarios, estamos desarrollando una nueva versi\u00f3n de la aplicaci\u00f3n monol\u00edtica, que ya no contiene este proceso. De hecho, tenemos en modo piloto la combinaci\u00f3n del monolito y el microservicio.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/27e98812746bb7f142fa3a3c3a03b52f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCon un piloto exitoso, entendemos que la nueva configuraci\u00f3n realmente funciona, podemos eliminar el viejo monolito de la ecuaci\u00f3n y dejar la nueva configuraci\u00f3n en el lugar de la antigua soluci\u00f3n.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/11dcf1d771b57d3921c0aa91b82646e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn resumen, utilizamos pr\u00e1cticamente todos los m\u00e9todos existentes para dividir el c\u00f3digo fuente del monolito. Todos ellos nos permiten reducir el tama\u00f1o de las partes de la aplicaci\u00f3n y trasladarlas a nuevas bibliotecas, creando un c\u00f3digo fuente de mayor calidad.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"9\"><\/a><\/noindex><b><\/p>\n<h3>Trabajo con la base de datos<\/h3>\n<p><\/b><br \/>\nLa base de datos es m\u00e1s dif\u00edcil de dividir que el c\u00f3digo fuente, ya que contiene no solo el esquema actual, sino tambi\u00e9n datos hist\u00f3ricos acumulados.<\/p>\n<p>Nuestra base de datos, al igual que muchas otras, ten\u00eda otra desventaja importante: su gran tama\u00f1o. Esta base de datos fue dise\u00f1ada de acuerdo con la compleja l\u00f3gica empresarial del monolito, y entre las tablas de varios contextos limitados se acumularon v\u00ednculos.<\/p>\n<p>En nuestro caso, para colmo de males (base de datos grande, numerosos v\u00ednculos, a veces l\u00edmites poco claros entre las tablas), surgi\u00f3 un problema que se encuentra en muchos grandes proyectos: el uso del patr\u00f3n de base de datos compartida. Los datos se extra\u00edan de las tablas a trav\u00e9s de views, mediante replicaci\u00f3n y se trasladaban a otros sistemas donde se necesitaba esta replicaci\u00f3n. Como resultado, no pod\u00edamos mover las tablas a un esquema separado porque estaban siendo utilizadas activamente.<\/p>\n<p>La segmentaci\u00f3n nos ayuda con la mencionada divisi\u00f3n en contextos limitados en el c\u00f3digo. Normalmente, nos proporciona una buena visi\u00f3n de c\u00f3mo dividimos los datos a nivel de base de datos. Entendemos qu\u00e9 tablas pertenecen a un contexto limitado y cu\u00e1les a otro.<\/p>\n<p>Hemos aplicado dos enfoques globales para separar la base de datos: separaci\u00f3n de tablas existentes y separaci\u00f3n con reestructuraci\u00f3n.<\/p>\n<p>La separaci\u00f3n de tablas existentes es un m\u00e9todo que se aplica bien cuando la estructura de datos es de calidad, satisface los requisitos comerciales y todos est\u00e1n de acuerdo. En este caso, podemos destacar como un esquema separado las tablas existentes.<\/p>\n<p>La separaci\u00f3n con reestructuraci\u00f3n es necesaria cuando el modelo de negocio ha cambiado dr\u00e1sticamente y las tablas ya no nos satisfacen en absoluto.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"10\"><\/a><\/noindex><b>Separaci\u00f3n de tablas existentes.<\/b> Necesitamos determinar qu\u00e9 vamos a separar. Sin este conocimiento, no podremos avanzar, y aqu\u00ed nos ayudar\u00e1 la separaci\u00f3n de contextos limitados en el c\u00f3digo. Por lo general, si logramos comprender los l\u00edmites de los contextos en el c\u00f3digo fuente, se hace claro qu\u00e9 tablas deben estar en la lista para ser separadas.<\/p>\n<p>Imaginemos que tenemos una soluci\u00f3n en la que dos m\u00f3dulos del monolito interact\u00faan con una \u00fanica base de datos. Necesitamos hacer que el segmento de tablas separadas sea accedido solo por un m\u00f3dulo, mientras que el otro comience a interactuar con \u00e9l a trav\u00e9s de la API. Para comenzar, es suficiente que solo se puedan realizar escrituras a trav\u00e9s de la API. Esta es una condici\u00f3n necesaria para poder hablar de la independencia de los microservicios. Las conexiones de lectura pueden permanecer, mientras no haya un gran problema con ello.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/1602637ad752ac055f475cfa45d95e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEl siguiente paso es que ya podemos extraer el segmento de c\u00f3digo que trabaja con las tablas separadas, con o sin reestructuraci\u00f3n, a un microservicio separado y ejecutarlo en un proceso y contenedor independientes. Este ser\u00e1 un servicio separado con conexi\u00f3n a la base de datos del monolito y aquellas tablas que no est\u00e1n directamente relacionadas con \u00e9l. El monolito seguir\u00e1 interactuando en lectura con la parte separada. <\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/36011f4e6be4f6a2f19f2f074b645dcb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nM\u00e1s adelante, eliminaremos esta conexi\u00f3n, es decir, tambi\u00e9n trasladaremos la lectura de datos de la aplicaci\u00f3n monol\u00edtica de las tablas separadas a trav\u00e9s de la API.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/290f91bbfccac2a4b384078e4cf4e337.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA continuaci\u00f3n, extraeremos de la base de datos general las tablas con las que trabaja solo el nuevo microservicio. Podemos mover las tablas a un esquema separado o incluso a una base de datos f\u00edsica separada. Queda una conexi\u00f3n de lectura entre el microservicio y la base de datos del monolito, pero no hay nada de qu\u00e9 preocuparse; en tal configuraci\u00f3n, puede funcionar durante un tiempo razonablemente largo.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/ab947ac6a38ffbccd4e2b51103aef609.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEl \u00faltimo paso es eliminar todas las relaciones por completo. En este caso, es posible que necesitemos la migraci\u00f3n de datos desde la base de datos principal. A veces, queremos reutilizar en varias bases algunos datos replicables desde sistemas externos o diccionarios. Esto ocurre peri\u00f3dicamente en nuestro caso.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/f40cf17dd56b9575751e370c44f08344.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<noindex><a rel=\"nofollow\" name=\"11\"><\/a><\/noindex><b>Departamento de reestructuraci\u00f3n.<\/b> Este m\u00e9todo es muy similar al primero, solo que va en orden inverso. De inmediato se destaca una nueva base de datos y un nuevo microservicio que interact\u00faa con el monolito a trav\u00e9s de API. Sin embargo, permanece un conjunto de tablas de BD que queremos eliminar en el futuro. Ya no las necesitaremos; en el nuevo modelo las hemos reemplazado.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/c94932033e47cfa1fd56595ab9a19246.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPara que este esquema funcione, probablemente necesitaremos un per\u00edodo de transici\u00f3n.<\/p>\n<p>A continuaci\u00f3n, hay dos enfoques posibles.<\/p>\n<p><b>Primero<\/b>: duplicamos todos los datos en las nuevas y viejas bases. En este caso, tenemos redundancia de datos, pueden surgir problemas de sincronizaci\u00f3n. Pero a cambio, podemos tener dos clientes diferentes. Uno trabajar\u00e1 con la nueva versi\u00f3n, el otro con la antigua.<\/p>\n<p><b>Segundo<\/b>: separamos los datos por alguna caracter\u00edstica comercial. Por ejemplo, ten\u00edamos 5 productos en el sistema que se almacenan en la antigua base de datos. El sexto, en el marco de una nueva tarea comercial, lo colocamos en la nueva BD. Pero necesitaremos un API Gateway que sincronice estos datos y muestre al cliente de d\u00f3nde y qu\u00e9 tomar.<\/p>\n<p>Ambos enfoques son viables, elija seg\u00fan la situaci\u00f3n.<\/p>\n<p>Despu\u00e9s de asegurarnos de que todo funcione, se puede desconectar la parte del monolito que trabaja con las antiguas estructuras de BD. <\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/973bf5015bdf49a290a5b901f89628cc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEl \u00faltimo paso ser\u00e1 eliminar las viejas estructuras de datos. <\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/fe83acc07077b7eb3717138e3c20c005.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nResumiendo, podemos decir que tenemos problemas con la BD: es m\u00e1s dif\u00edcil trabajar con ella en comparaci\u00f3n con el c\u00f3digo fuente, es m\u00e1s complicado dividirla, pero se puede y se debe hacer. Hemos encontrado algunas maneras que permiten hacerlo de manera bastante segura; de hecho, cometer un error con los datos es m\u00e1s f\u00e1cil que con el c\u00f3digo fuente. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"12\"><\/a><\/noindex><b><\/p>\n<h3>Trabajo con el c\u00f3digo fuente<\/h3>\n<p><\/b><br \/>\nAs\u00ed es como se ve\u00eda el esquema del c\u00f3digo fuente cuando comenzamos a analizar el proyecto monol\u00edtico.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/a6d886e37117ccf8f63106d6616aa653.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSe puede dividir condicionalmente en tres capas. Esta es la capa de m\u00f3dulos ejecutables, plugins, servicios y actividades individuales. De hecho, estos eran los puntos de entrada dentro de la soluci\u00f3n monol\u00edtica. Todos estaban firmemente interconectados por la capa Com\u00fan. En esta capa se encontraba la l\u00f3gica empresarial que era utilizada en conjunto por los servicios, as\u00ed como numerosas interconexiones. Cada servicio y plugin utilizaba hasta 10 o m\u00e1s ensamblados comunes, dependiendo de su tama\u00f1o y la \u00e9tica de los desarrolladores.<\/p>\n<p>Tuvimos la suerte de contar con bibliotecas de infraestructura que se pod\u00edan utilizar de forma independiente. <\/p>\n<p>A veces surg\u00eda la situaci\u00f3n en la que algunos objetos Comunes en realidad no pertenec\u00edan a esta capa, sino que eran bibliotecas de infraestructura. Esto se resolv\u00eda mediante un cambio de nombre.<\/p>\n<p>Los contextos limitados eran los que m\u00e1s preocupaci\u00f3n generaban. A veces, 3-4 contextos se mezclaban en un solo ensamblado Com\u00fan y se utilizaban entre s\u00ed en el marco de funciones empresariales. Era necesario entender d\u00f3nde se pod\u00eda dividir esto y cu\u00e1les eran los l\u00edmites, y qu\u00e9 hacer a continuaci\u00f3n con el mapeo de esta divisi\u00f3n a los ensamblados del c\u00f3digo fuente.<\/p>\n<p>Formulamos varias reglas para el proceso de separaci\u00f3n de c\u00f3digo.<\/p>\n<p><b>Primera<\/b>: ya no quer\u00edamos compartir la l\u00f3gica empresarial entre servicios, actividades y plugins. Quer\u00edamos hacer que la l\u00f3gica empresarial fuese independiente dentro de los microservicios. Por otro lado, los microservicios, en un mundo ideal, se perciben como servicios que existen de manera completamente independiente. Creo que este enfoque es un poco derrochador, y es dif\u00edcil lograrlo, ya que, por ejemplo, los servicios en C# estar\u00e1n conectados a la biblioteca est\u00e1ndar de todos modos. Nuestro sistema est\u00e1 escrito en C#, por lo que no hemos tenido que utilizar otras tecnolog\u00edas hasta ahora. Por lo tanto, decidimos que pod\u00edamos permitirnos utilizar ensamblados t\u00e9cnicos comunes. Lo importante es que no contengan fragmentos de l\u00f3gica empresarial. Si tiene un envoltorio pr\u00e1ctico sobre el ORM que utiliza, copiarlo de un servicio a otro puede resultar muy costoso.<\/p>\n<p>Nuestro equipo es un gran admirador del dise\u00f1o orientado a dominios, por lo que la \"arquitectura cebolla\" se ajusta perfectamente a nosotros. La base de nuestros servicios se convirti\u00f3 no en una capa de acceso a datos, sino en una ensambladura con l\u00f3gica de dominio que contiene \u00fanicamente la l\u00f3gica empresarial y carece de v\u00ednculos con la infraestructura. As\u00ed, podemos desarrollar de forma independiente la ensambladura de dominio para resolver problemas relacionados con los frameworks.<\/p>\n<p>En esta etapa, nos encontramos con el primer problema serio. El servicio deb\u00eda referirse a una ensambladura de dominio, quer\u00edamos que la l\u00f3gica fuera independiente, y el principio DRY se interpon\u00eda mucho. Los desarrolladores quer\u00edan evitar la duplicaci\u00f3n reutilizando clases de ensambladuras adyacentes, y como resultado, los dominios nuevamente comenzaron a vincularse entre s\u00ed. Analizamos los resultados y decidimos que, posiblemente, el problema radicaba tambi\u00e9n en la manera en que se organiza el almacenamiento del c\u00f3digo fuente. Ten\u00edamos un gran repositorio donde estaban todos los c\u00f3digos fuente. Era muy dif\u00edcil construir una soluci\u00f3n para todo el proyecto en la m\u00e1quina local. Por lo tanto, se creaban soluciones peque\u00f1as y separadas para partes del proyecto y nadie prohib\u00eda a\u00f1adir una ensambladura com\u00fan o de dominio y reutilizarla. La \u00fanica herramienta que nos imped\u00eda hacerlo era la revisi\u00f3n de c\u00f3digo. Pero a veces, incluso esta fallaba.<\/p>\n<p>Entonces comenzamos a pasar a un modelo con repositorios separados. La l\u00f3gica empresarial dej\u00f3 de filtrarse de un servicio a otro, los dominios realmente se volvieron independientes. Los contextos delimitados se mantienen con mayor claridad. \u00bfC\u00f3mo reutilizamos las bibliotecas de infraestructura en este caso? Las destacamos en un repositorio separado, luego las colocamos en paquetes Nuget, que almacenamos en Artifactory. Con cualquier cambio, la ensambladura y publicaci\u00f3n se llevan a cabo autom\u00e1ticamente.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/8ddbc750dc7c6d397a459acf7825de90.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNuestros servicios comenzaron a referirse a los paquetes de infraestructura internos de la misma manera que a los externos. Descargamos las bibliotecas externas de Nuget. Para trabajar con Artifactory, donde almacenamos estos paquetes, aplicamos dos gestores de paquetes. En peque\u00f1os repositorios tambi\u00e9n usamos Nuget. En repositorios con varios servicios, utilizamos Paket, que garantiza una mayor coherencia de versiones entre los m\u00f3dulos.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/672a25a70a481bff68baebe963184ccd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDe este modo, al trabajar en el c\u00f3digo fuente, al modificar un poco la arquitectura y dividir los repositorios, hacemos que nuestros servicios sean m\u00e1s independientes.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"13\"><\/a><\/noindex><b><\/p>\n<h3>Problemas de infraestructura<\/h3>\n<p><\/b><br \/>\nLa mayor\u00eda de las desventajas al pasar a microservicios est\u00e1n relacionadas con la infraestructura. Necesitar\u00e1 un despliegue automatizado y nuevas bibliotecas para la infraestructura.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"16\"><\/a><\/noindex><b>Instalaci\u00f3n manual en entornos<\/b><\/p>\n<p>Inicialmente, configur\u00e1bamos la soluci\u00f3n en los entornos de manera manual. Para automatizar este proceso, creamos un pipeline de CI\/CD. Elegimos el proceso de entrega continua, ya que el despliegue continuo no es viable para nosotros en t\u00e9rminos de procesos de negocio. Por lo tanto, el env\u00edo a producci\u00f3n se realiza con un bot\u00f3n, mientras que las pruebas son autom\u00e1ticas.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/0fc092326a48813398c6f3a031197bab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUtilizamos Atlassian, Bitbucket para almacenar los c\u00f3digos fuente y Bamboo para la construcci\u00f3n. Nos gusta escribir scripts de construcci\u00f3n en Cake, porque es el mismo C#. Los paquetes listos llegan a Artifactory, y Ansible se despliega autom\u00e1ticamente en los servidores de prueba, donde pueden ser probados de inmediato.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/fcc743cfaa4a24b906ceeb40ec1ba0a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<noindex><a rel=\"nofollow\" name=\"14\"><\/a><\/noindex><b><\/p>\n<h3>Registro separado<\/h3>\n<p><\/b><br \/>\nEn su momento, una de las ideas del monolito era proporcionar un registro conjunto. Tambi\u00e9n necesit\u00e1bamos entender qu\u00e9 hacer con los registros individuales que est\u00e1n en los discos. Los logs se escriben en archivos de texto. Decidimos utilizar la pila ELK est\u00e1ndar. No escribimos directamente en ELK a trav\u00e9s de los proveedores, sino que decidimos mejorar los logs de texto y registrar los IDs de trazabilidad como un identificador, a\u00f1adiendo el nombre del servicio para que esos logs pudieran ser analizados posteriormente.<\/p>\n<p><img decoding=\"async\" alt=\"La transici\u00f3n de monolitos a microservicios: historia y pr\u00e1ctica\" src=\"\/wp-content\/uploads\/2019\/07\/8e58c66ac134e65abe34b59939f31483.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCon Filebeat tenemos la capacidad de recopilar nuestros registros desde <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/es\/server\/\"   title=\"servidores\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1338\">servidores<\/a>, luego transformarlos, construir consultas en la interfaz de usuario con Kibana y ver c\u00f3mo fue la llamada entre los servicios. Esto se ve muy beneficiado por el ID de trazabilidad.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"15\"><\/a><\/noindex><b><\/p>\n<h3>Pruebas y depuraci\u00f3n de servicios relacionados<\/h3>\n<p><\/b><br \/>\nAl principio, no entend\u00edamos completamente c\u00f3mo depurar los servicios en desarrollo. Con el monolito era sencillo, lo ejecut\u00e1bamos en la m\u00e1quina local. Al principio, tambi\u00e9n intentamos hacer lo mismo con los microservicios, pero a veces para ejecutar un microservicio completo es necesario iniciar varios otros, lo cual es inconveniente. Nos dimos cuenta de que necesit\u00e1bamos adoptar un modelo en el que dej\u00e1ramos en la m\u00e1quina local solo el o los servicios que quer\u00edamos depurar. Los dem\u00e1s servicios se utilizan desde servidores con una configuraci\u00f3n id\u00e9ntica a la de producci\u00f3n. Despu\u00e9s de la depuraci\u00f3n, en la fase de prueba, solo se despliegan los servicios modificados en el servidor de pruebas para cada tarea. De este modo, la soluci\u00f3n se prueba tal como estar\u00e1 en producci\u00f3n en el futuro.<\/p>\n<p>Hay servidores en los que solo est\u00e1n las versiones de producci\u00f3n de los servicios. Estos servidores son necesarios en caso de incidentes, para verificar la entrega antes del despliegue y para formaciones internas.<\/p>\n<p>Hemos a\u00f1adido un proceso de pruebas autom\u00e1ticas utilizando la popular biblioteca Specflow. Las pruebas se ejecutan autom\u00e1ticamente con NUnit justo despu\u00e9s del despliegue desde Ansible. Si la cobertura de la tarea es completamente autom\u00e1tica, no hay necesidad de pruebas manuales. Aunque a veces se requiere una prueba manual adicional. Para determinar qu\u00e9 pruebas ejecutar para una tarea espec\u00edfica, utilizamos etiquetas en Jira.<\/p>\n<p>Adem\u00e1s, ha crecido la necesidad de realizar pruebas de carga, que anteriormente se llevaban a cabo solo en raras ocasiones. Para ejecutar las pruebas utilizamos JMeter, para almacenarlas \u2014 InfluxDB, y para construir gr\u00e1ficos del proceso \u2014 Grafana.<\/p>\n<p><b><\/p>\n<h3>\u00bfQu\u00e9 hemos logrado?<\/h3>\n<p><\/b><br \/>\nEn primer lugar, nos hemos deshecho del concepto de \"lanzamiento\". Han desaparecido los monstruosos lanzamientos de dos meses, cuando esta maquinaria se desplegaba en el entorno de producci\u00f3n, interrumpiendo temporalmente los procesos de negocio. Ahora desplegamos servicios en promedio cada 1.5 d\u00edas, agrup\u00e1ndolos, porque entran en producci\u00f3n tras su aprobaci\u00f3n.<\/p>\n<p>En nuestro sistema no hay fallos fatales. Si lanzamos un microservicio con un error, la funcionalidad relacionada se ver\u00e1 afectada, pero el resto de la funcionalidad no se ver\u00e1 perjudicada. Esto mejora significativamente la experiencia del usuario.<\/p>\n<p>Podemos gestionar el esquema de implementaci\u00f3n. Se pueden destacar grupos de servicios por separado del resto de la soluci\u00f3n, si es necesario.<\/p>\n<p>Adem\u00e1s, hemos reducido considerablemente el problema de la gran cola de tareas pendientes. Tenemos equipos de productos separados que trabajan de manera independiente en parte de los servicios. Aqu\u00ed el proceso de Scrum encaja bien. Un equipo espec\u00edfico puede tener un propietario de producto separado que le asigna tareas. <\/p>\n<p><b><\/p>\n<h3>Curr\u00edculum<\/h3>\n<p><\/b><\/p>\n<ul>\n<li>Los microservicios son adecuados para la descomposici\u00f3n de sistemas complejos. A trav\u00e9s del proceso empezamos a entender lo que hay en nuestro sistema, cu\u00e1les son los contextos limitados y d\u00f3nde est\u00e1n sus l\u00edmites. Esto permite distribuir correctamente las modificaciones entre los m\u00f3dulos y evitar la confusi\u00f3n del c\u00f3digo. <\/li>\n<li>Los microservicios ofrecen ventajas organizativas. A menudo se habla de ellos solo como una arquitectura, pero cualquier arquitectura es necesaria para satisfacer las necesidades del negocio, no por s\u00ed misma. Por lo tanto, podemos decir que los microservicios son buenos para abordar tareas con peque\u00f1os equipos, considerando que Scrum es muy popular en la actualidad.<\/li>\n<li>La separaci\u00f3n es un proceso iterativo. No se puede tomar una aplicaci\u00f3n y simplemente dividirla en microservicios. El producto resultante probablemente no ser\u00e1 funcional. Al destacar los microservicios, es beneficioso reescribir el legado existente, es decir, transformarlo en un c\u00f3digo que nos guste y que satisfaga mejor las necesidades del negocio en t\u00e9rminos de funcionalidad y velocidad.\n<p><i>Una peque\u00f1a advertencia:<\/i> los costos de transici\u00f3n a microservicios son bastante significativos. Solo resolver el problema de la infraestructura llev\u00f3 mucho tiempo. Por lo tanto, si tienes una aplicaci\u00f3n peque\u00f1a que no requiere una escalabilidad espec\u00edfica, y no hay un gran n\u00famero de clientes compitiendo por la atenci\u00f3n y tiempo de tu equipo, tal vez los microservicios no sean lo que necesitas hoy. Es bastante costoso. Si comienzas el proceso con microservicios, los costos iniciales ser\u00e1n mayores que si comenzaras el mismo proyecto con el desarrollo de un monolito. <\/p>\n<p>P.D. Un relato m\u00e1s emocional (como si te hablara personalmente) \u2013 en <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=qTNbx18DzpQ\">el enlace<\/a><\/noindex>. <br \/>\nAqu\u00ed est\u00e1 la versi\u00f3n completa de la presentaci\u00f3n.<\/li>\n<\/ul>\n<p>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/raiffeisenbank\/blog\/458404\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u0432 \u043d\u0430\u0431\u043e\u0440 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 2000. \u041f\u0435\u0440\u0432\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u044b\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 Visual Basic 6. \u0421 \u0442\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0442\u0430\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043d\u0430 \u044d\u0442\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a IDE [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":26858,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35906","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u0432 \u043d\u0430\u0431\u043e\u0440 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 2000.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043e\u0442 \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u043a \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c: \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u0432 \u043d\u0430\u0431\u043e\u0440 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 2000.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:07:29+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:07:29+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Transici\u00f3n de monolito a microservicios: historia y pr\u00e1ctica | ProHoster","description":"En este art\u00edculo, hablar\u00e9 sobre c\u00f3mo el proyecto en el que trabajo se transform\u00f3 de un gran monolito a un conjunto de microservicios. El proyecto comenz\u00f3 su historia hace bastante tiempo, a principios de 2000.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043e\u0442 \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u043a \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c: \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 | ProHoster","og:description":"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u0432 \u043d\u0430\u0431\u043e\u0440 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 2000.","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:07:29+00:00","article:modified_time":"2019-10-31T19:07:29+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35906","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-02-09 17:04:56","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:54:38","updated":"2026-02-09 17:04:56","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/35906","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=35906"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/35906\/revisions"}],"predecessor-version":[{"id":158582,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/35906\/revisions\/158582"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/26858"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=35906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=35906"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=35906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}