{"id":52389,"date":"2019-11-07T00:00:00","date_gmt":"2019-11-06T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions"},"modified":"2020-02-18T14:00:05","modified_gmt":"2020-02-18T11:00:05","slug":"kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","title":{"rendered":"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/fe7af07f3ac5ca4e75009993b742293e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00a1Hola, Habr! Soy Artem Karamychev, l\u00edder del equipo de administraci\u00f3n de sistemas. <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/\">Soluciones en la Nube de Mail.Ru (MCS)<\/a><\/noindex>. En el \u00faltimo a\u00f1o, hemos lanzado muchos nuevos productos. Quer\u00edamos que los servicios de API fueran f\u00e1cilmente escalables, tolerantes a fallos y listos para un r\u00e1pido aumento de la carga del usuario. Nuestra plataforma est\u00e1 implementada en OpenStack, y quiero contarles qu\u00e9 problemas de tolerancia a fallos de los componentes tuvimos que resolver para obtener un sistema tolerante a fallos. Creo que esto ser\u00e1 interesante para aquellos que tambi\u00e9n est\u00e1n desarrollando productos en OpenStack.<\/p>\n<p>La tolerancia a fallos general de la plataforma se compone de la resiliencia de sus componentes. As\u00ed que pasaremos gradualmente por todos los niveles donde identificamos riesgos y los cerramos.<\/p>\n<p>La versi\u00f3n en video de esta historia, que se basa en una presentaci\u00f3n en la conferencia Uptime day 4, organizada por <noindex><a rel=\"nofollow\" href=\"http:\/\/www.itsumma.ru\">ITSumma<\/a><\/noindex>, se puede ver <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=3b06MVou-vg&amp;list=PLmXjIrLllpkjwuIGkzBkLbI7oHtUadmvZ&amp;index=5\">en el canal de YouTube de Uptime Community<\/a><\/noindex>. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Tolerancia a fallos de la arquitectura f\u00edsica<\/h2>\n<p>\nLa parte p\u00fablica de la nube MCS ahora se basa en dos centros de datos de nivel Tier III, entre ellos hay fibra oscura propia, reservada a nivel f\u00edsico por diferentes rutas, con una capacidad de 200 Gbps. El nivel Tier III proporciona el nivel necesario de tolerancia a fallos de la infraestructura f\u00edsica. <\/p>\n<p>La fibra oscura est\u00e1 reservada tanto a nivel f\u00edsico como l\u00f3gico. El proceso de reserva de canales fue iterativo, surgieron problemas y estamos mejorando constantemente la conexi\u00f3n entre los centros de datos. <\/p>\n<blockquote><p>Por ejemplo, no hace mucho, durante trabajos en una alcantarilla cerca de uno de los centros de datos, un excavadora perfor\u00f3 una tuber\u00eda, dentro de esta tuber\u00eda se encontraron tanto el cable \u00f3ptico principal como el de reserva. Nuestro canal de comunicaci\u00f3n tolerante a fallos con el centro de datos result\u00f3 ser vulnerable en un punto, en la alcantarilla. Por lo tanto, perdimos parte de la infraestructura. Sacamos conclusiones, tomamos una serie de acciones, incluida la instalaci\u00f3n de una \u00f3ptica adicional a trav\u00e9s de la alcantarilla vecina.<\/p><\/blockquote>\n<p>\nEn los centros de datos, hay puntos de presencia de proveedores de telecomunicaciones a los que transmitimos nuestros prefijos a trav\u00e9s de BGP. Se selecciona la mejor m\u00e9trica para cada direcci\u00f3n de red, lo que permite ofrecer a diferentes clientes la mejor calidad de conexi\u00f3n. Si la conexi\u00f3n a trav\u00e9s de un proveedor se interrumpe, reconfiguramos nuestra ruta a trav\u00e9s de los proveedores disponibles.<\/p>\n<p>En caso de una falla del proveedor, cambiamos autom\u00e1ticamente al siguiente. Si uno de los centros de datos falla, tenemos una copia espejo de nuestros servicios en el segundo centro de datos que asume toda la carga.<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/295ca212f48dd074d834154666e5b0c3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Resiliencia de la infraestructura f\u00edsica<\/i><\/p>\n<h2>Lo que utilizamos para la resiliencia a nivel de aplicaciones<\/h2>\n<p>\nNuestro servicio se basa en varios componentes de c\u00f3digo abierto. <\/p>\n<p><b>ExaBGP<\/b> \u2014 un servicio que implementa una serie de funciones utilizando el protocolo de enrutamiento din\u00e1mico basado en BGP. Lo utilizamos activamente para anunciar nuestras direcciones IP p\u00fablicas, a trav\u00e9s de las cuales los usuarios acceden a la API.<\/p>\n<p><b>HAProxy<\/b> \u2014 un balanceador de carga de alta demanda que permite configurar reglas de balanceo de tr\u00e1fico muy flexibles en diferentes niveles del modelo OSI. Lo utilizamos para balancear ante todos los servicios: bases de datos, intermediarios de mensajes, servicios API, servicios web, nuestros proyectos internos: todo est\u00e1 detr\u00e1s de HAProxy.<\/p>\n<p><b>API application<\/b> \u2014 una aplicaci\u00f3n web escrita en python, con la que el usuario gestiona su infraestructura, su servicio.<\/p>\n<p><b>Worker application <\/b>(en adelante simplemente worker) \u2014 en los servicios de OpenStack, es un demonio de infraestructura que permite transmitir comandos API a la infraestructura. Por ejemplo, la creaci\u00f3n de un disco se lleva a cabo precisamente en el worker, mientras que la solicitud de creaci\u00f3n se realiza en la API application. <\/p>\n<h2>Arquitectura est\u00e1ndar de OpenStack Application<\/h2>\n<p>\nLa mayor\u00eda de los servicios desarrollados para OpenStack intentan seguir una \u00fanica paradoja. Un servicio generalmente se compone de 2 partes: API y workers (ejecutores de backend). Por lo general, API es una aplicaci\u00f3n WSGI en Python, que se ejecuta ya sea como un proceso independiente (daemon) o utilizando un servidor web ya configurado como Nginx o Apache. El API procesa la solicitud del usuario y pasa instrucciones adicionales para que las ejecute la aplicaci\u00f3n worker. La transmisi\u00f3n ocurre a trav\u00e9s de un corredor de mensajes, que generalmente es RabbitMQ, siendo mal soportados los dem\u00e1s. Cuando los mensajes llegan al corredor, los workers los procesan y, de ser necesario, devuelven una respuesta. <\/p>\n<p>Esta paradoja implica puntos de falla comunes aislados: RabbitMQ y la base de datos. Sin embargo, RabbitMQ est\u00e1 aislado dentro de un solo servicio y, en teor\u00eda, puede ser individual para cada servicio. Por lo tanto, en MCS, separamos al m\u00e1ximo estos servicios, creando una base de datos separada y un RabbitMQ separado para cada proyecto distinto. Este enfoque es beneficioso ya que, en caso de una falla en algunos de los puntos vulnerables, no se rompe todo el servicio, sino solo su parte.<\/p>\n<p>La cantidad de aplicaciones worker no est\u00e1 limitada, por lo que el API puede escalar horizontalmente f\u00e1cilmente detr\u00e1s de balanceadores para aumentar el rendimiento y la tolerancia a fallos.<\/p>\n<blockquote><p>En algunos servicios es necesaria la coordinaci\u00f3n dentro del servicio, cuando hay operaciones secuenciales complejas entre API y workers. En este caso, se utiliza un centro de coordinaci\u00f3n \u00fanico, un sistema de cl\u00faster del tipo Redis, Memcache, etcd, que permite que un worker le diga a otro que esta tarea est\u00e1 asignada a \u00e9l (\"t\u00fa, por favor, no la tomes\"). Nosotros usamos etcd. Generalmente, los workers se comunican activamente con la base de datos, escribiendo y leyendo informaci\u00f3n de all\u00ed. Como base de datos, utilizamos MariaDB, que se encuentra en un cl\u00faster multimaster.\n<\/p><\/blockquote>\n<p>\nEste cl\u00e1sico servicio \u00fanico est\u00e1 organizado de una manera com\u00fanmente aceptada para OpenStack. Se puede considerar como un sistema cerrado, para el cual las formas de escalado y tolerancia a fallos son bastante evidentes. Por ejemplo, para la tolerancia a fallos, basta con colocar un balanceador frente al API. El escalado de los workers se logra aumentando su n\u00famero. <\/p>\n<p>El punto d\u00e9bil de todo el esquema son RabbitMQ y MariaDB. Su arquitectura merece un art\u00edculo aparte. En este art\u00edculo, quiero centrarme en la tolerancia a fallos de la API.<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/f39e5a8ae350864e311bf4db3b9c34b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Arquitectura de Openstack Application. Balanceo y tolerancia a fallos de la plataforma en la nube<\/i><\/p>\n<h2>Hacemos que el balanceador HAProxy sea tolerante a fallos con la ayuda de ExaBGP<\/h2>\n<p>\nPara que nuestras API sean escalables, r\u00e1pidas y tolerantes a fallos, les hemos colocado un balanceador. Elegimos HAProxy. En mi opini\u00f3n, cuenta con todas las caracter\u00edsticas necesarias para nuestra tarea: balanceo en varios niveles de OSI, interfaz de gesti\u00f3n, flexibilidad y escalabilidad, una gran cantidad de m\u00e9todos de balanceo, y soporte para tablas de sesiones.<\/p>\n<p>El primer problema que hab\u00eda que resolver era la tolerancia a fallos del propio balanceador. Simplemente instalar un balanceador tambi\u00e9n crea un punto de falla: si el balanceador falla, el servicio cae. Para evitar que esto suceda, utilizamos HAProxy junto con ExaBGP.<\/p>\n<p>ExaBGP permite implementar un mecanismo de verificaci\u00f3n del estado del servicio. Usamos este mecanismo para verificar la operatividad de HAProxy y, en caso de problemas, desactivar el servicio HAProxy desde BGP. <\/p>\n<p><b>Esquema ExaBGP+HAProxy<\/b><\/p>\n<ol>\n<li>Instalamos el software necesario, ExaBGP y HAProxy, en tres servidores. <\/li>\n<li>Creamos una interfaz loopback en cada uno de los servidores.<\/li>\n<li>En los tres servidores configuramos la misma direcci\u00f3n IP p\u00fablica en esta interfaz.<\/li>\n<li>La direcci\u00f3n IP p\u00fablica se anuncia en Internet a trav\u00e9s de ExaBGP. <\/li>\n<\/ol>\n<p>\nLa tolerancia a fallos se logra anunciando la misma direcci\u00f3n IP desde los tres servidores. Desde el punto de vista de la red, la misma direcci\u00f3n est\u00e1 disponible desde tres diferentes next hops. El enrutador ve tres rutas iguales, elige la m\u00e1s prioritaria seg\u00fan su propia m\u00e9trica (que generalmente es la misma opci\u00f3n), y el tr\u00e1fico solo va a uno de los servidores. <\/p>\n<p>En caso de problemas con HAProxy o ca\u00edda de un servidor, ExaBGP deja de anunciar la ruta, y el tr\u00e1fico se redirige suavemente a otro servidor. <\/p>\n<p>De esta manera hemos logrado la tolerancia a fallos del balanceador.<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/9fba0718176dc1266f25a2c01ec87348.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Tolerancia a fallos de los balanceadores HAProxy<\/i><\/p>\n<p>El esquema result\u00f3 ser no perfecto: aprendimos a hacer redundante HAProxy, pero no aprendimos a distribuir la carga dentro de los servicios. Por lo tanto, ampliamos un poco este esquema: pasamos a balancear entre varias direcciones IP p\u00fablicas.<\/p>\n<h2>Balanceo basado en DNS m\u00e1s BGP<\/h2>\n<p>\nA\u00fan queda sin resolver la cuesti\u00f3n de la balanceo de carga ante nuestros HAProxy. Sin embargo, es posible solucionarlo de manera bastante sencilla, como lo hicimos nosotros.<\/p>\n<p>Para balancear tres servidores se necesitar\u00e1n 3 direcciones IP p\u00fablicas y el viejo y confiable DNS. Cada una de estas direcciones se define en la interfaz de loopback de cada HAProxy y se anuncia en internet. <\/p>\n<p>En OpenStack, se utiliza un cat\u00e1logo de servicios para gestionar los recursos, donde se establece el endpoint API de cada servicio. En este cat\u00e1logo, especificamos el nombre de dominio \u2014 public.infra.mail.ru, que se resuelve a trav\u00e9s de DNS con tres direcciones IP diferentes. Como resultado, obtenemos una distribuci\u00f3n de carga entre las tres direcciones mediante DNS. <\/p>\n<p>Pero dado que al anunciar las direcciones IP p\u00fablicas no gestionamos las prioridades de selecci\u00f3n del servidor, esto a\u00fan no es un balanceo. Por lo general, solo se seleccionar\u00e1 un servidor seg\u00fan la antig\u00fcedad de la direcci\u00f3n IP, mientras que los otros dos quedar\u00e1n inactivos, ya que no se especifican m\u00e9tricas en BGP.<\/p>\n<p>Comenzamos a anunciar rutas a trav\u00e9s de ExaBGP con diferentes m\u00e9tricas. Cada balanceador anuncia las tres direcciones IP p\u00fablicas, pero una de ellas, la principal para ese balanceador, se anuncia con la m\u00e9trica m\u00e1s baja. As\u00ed que mientras los tres balanceadores est\u00e9n en funcionamiento, las solicitudes al primer IP van al primer balanceador, las solicitudes al segundo van al segundo, y al tercero, al tercero.<\/p>\n<p>\u00bfQu\u00e9 sucede en el momento en que uno de los balanceadores falla? Al fallar cualquiera de los balanceadores, su direcci\u00f3n principal a\u00fan se anuncia desde los otros dos y el tr\u00e1fico se redistribuye entre ellos. De este modo, entregamos al usuario a trav\u00e9s de DNS varias direcciones IP. Mediante balanceo por DNS y diferentes m\u00e9tricas, logramos una distribuci\u00f3n uniforme de la carga entre los tres balanceadores, sin perder la tolerancia a fallos.<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/1485367a934aea06b68c6d05c184d263.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Balanceo HAProxy basado en DNS + BGP<\/i><\/p>\n<h2>Interacci\u00f3n entre ExaBGP y HAProxy<\/h2>\n<p>\nAs\u00ed que hemos implementado la tolerancia a fallos en caso de que un servidor se caiga, basada en la interrupci\u00f3n del anuncio de rutas. Pero HAProxy tambi\u00e9n puede desconectarse por otras razones adem\u00e1s de la ca\u00edda del servidor: errores de administraci\u00f3n, fallos dentro del servicio. Queremos eliminar el balanceador da\u00f1ado de la carga en estos casos, lo cual requiere otro mecanismo. <\/p>\n<p>Por lo tanto, al ampliar el esquema anterior, implementamos un heartbeat entre ExaBGP y HAProxy. Esta es una implementaci\u00f3n de software para la interacci\u00f3n entre ExaBGP y HAProxy, donde ExaBGP utiliza scripts personalizados para verificar el estado de las aplicaciones.<\/p>\n<p>Para ello, es necesario configurar un verificador de salud en el archivo de configuraci\u00f3n de ExaBGP, que pueda comprobar el estado de HAProxy. En nuestro caso, configuramos un backend de salud en HAProxy, y desde ExaBGP comprobamos con una simple solicitud GET. Si el anuncio deja de realizarse, es probable que HAProxy no est\u00e9 funcionando, y no se debe anunciar. <\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/d5cda30043fe02ab81355b28c0d83ac6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Verificaci\u00f3n de Salud de HAProxy<\/i><\/p>\n<h2>Compa\u00f1eros de HAProxy: sincronizaci\u00f3n de sesiones <\/h2>\n<p>\nLo siguiente que hab\u00eda que hacer era sincronizar las sesiones. Al trabajar a trav\u00e9s de equilibradores de carga distribuidos, es dif\u00edcil mantener la informaci\u00f3n sobre las sesiones de los clientes. Pero HAProxy es uno de los pocos equilibradores que puede hacerlo gracias a la funcionalidad de Peers, que permite la transferencia de tablas de sesiones entre diferentes procesos de HAProxy. <\/p>\n<p>Existen diferentes m\u00e9todos de balanceo: simples, como <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Round-robin_(%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC)\">round-robin<\/a><\/noindex>, y avanzados, donde se recuerda la sesi\u00f3n del cliente, y siempre aterriza en el mismo servidor que antes. Quer\u00edamos implementar la segunda opci\u00f3n.<\/p>\n<p>En HAProxy, para la conservaci\u00f3n de las sesiones del cliente, se utiliza el mecanismo de stick-tables. Estas guardan la direcci\u00f3n IP original del cliente, la direcci\u00f3n del target elegido (backend) y cierta informaci\u00f3n operativa. Normalmente, las stick-tables se utilizan para conservar el par source-IP + destination-IP, lo cual es especialmente \u00fatil para aplicaciones que no pueden transmitir el contexto de la sesi\u00f3n del usuario al cambiar a otro equilibrador, por ejemplo, en el modo de balanceo RoundRobin.<\/p>\n<p>Si se le ense\u00f1a a la stick-table a moverse entre diferentes procesos de HAProxy (entre los cuales se realiza el balanceo), nuestros equilibradores podr\u00e1n trabajar con un solo conjunto de stick-tables. Esto permitir\u00e1 un cambio de red sin interrupciones para el cliente en caso de que uno de los equilibradores falle, y el manejo de las sesiones de los clientes continuar\u00e1 en los mismos backends que se eligieron previamente.<\/p>\n<p>Para un funcionamiento correcto, debe resolverse el problema de la direcci\u00f3n IP source del equilibrador desde el que se estableci\u00f3 la sesi\u00f3n. En nuestro caso, se trata de una direcci\u00f3n din\u00e1mica en la interfaz de loopback. <\/p>\n<p>El funcionamiento correcto de los pares solo se logra en ciertas condiciones. Es decir, los tiempos de espera de TCP deben ser lo suficientemente largos o el cambio debe ser lo suficientemente r\u00e1pido para que la sesi\u00f3n TCP no se interrumpa. Sin embargo, esto permite un cambio sin problemas. <\/p>\n<p>En nuestra IaaS, tenemos un servicio construido con esta misma tecnolog\u00eda. Es <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/app\/services\/infra\/balancers-list\/\">Load Balancer como servicio para OpenStack<\/a><\/noindex>, que se llama Octavia. Se basa en dos procesos de HAProxy y desde el principio incluye soporte para pares. En este servicio han demostrado ser muy efectivos.<\/p>\n<p>En la imagen se muestra esquem\u00e1ticamente el movimiento de las tablas de pares entre tres instancias de HAProxy, se propone una configuraci\u00f3n de c\u00f3mo se puede ajustar esto:<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/d31fab761da627923345b7ace7f0b943.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>HAProxy Peers (sincronizaci\u00f3n de sesiones)<\/i><\/p>\n<p>Si vas a implementar un esquema as\u00ed, debes probar su funcionamiento cuidadosamente. No es seguro que funcione de la misma manera en el 100% de los casos. Pero, al menos, no perder\u00e1s las tablas de stick cuando necesites recordar la IP de origen del cliente.<\/p>\n<h2>L\u00edmite en la cantidad de solicitudes simult\u00e1neas desde el mismo cliente<\/h2>\n<p>\nCualquier servicio accesible p\u00fablicamente, incluidos nuestros API, puede ser objeto de avalanchas de solicitudes. Las razones pueden ser muy variadas, desde errores de los usuarios hasta ataques deliberados. Nos someten peri\u00f3dicamente a DDoS por direcciones IP. Los clientes a menudo cometen errores en sus scripts, provocando mini-DDoS.<\/p>\n<p>De una forma u otra, es necesario prever una protecci\u00f3n adicional. Una soluci\u00f3n obvia es limitar la cantidad de solicitudes a la API y no desperdiciar tiempo de CPU en el procesamiento de solicitudes maliciosas.<\/p>\n<p>Para implementar tales limitaciones, usamos l\u00edmites de tasa, organizados sobre la base de HAProxy, con las mismas tablas de stick. Los l\u00edmites se configuran de manera bastante sencilla y permiten restringir al usuario en la cantidad de solicitudes a la API. El algoritmo recuerda la IP de origen desde la cual se realizan las solicitudes y limita la cantidad de solicitudes simult\u00e1neas de un mismo usuario. Por supuesto, hemos calculado el perfil promedio de carga en la API de cada servicio y hemos establecido un l\u00edmite de aproximadamente 10 veces mayor que este valor. Seguimos observando de cerca la situaci\u00f3n y manteniendo el pulso.<\/p>\n<p>\u00bfC\u00f3mo se ve esto en la pr\u00e1ctica? Tenemos clientes que utilizan constantemente nuestras API para el autoescalado. Crean alrededor de doscientos a trescientos m\u00e1quinas virtuales por la ma\u00f1ana y las eliminan por la tarde. Para OpenStack, crear una m\u00e1quina virtual, adem\u00e1s de los servicios PaaS, requiere al menos 1000 solicitudes API, ya que la interacci\u00f3n entre los servicios tambi\u00e9n se realiza a trav\u00e9s de la API. <\/p>\n<p>Estos cambios en las tareas generan una carga considerable. Evaluamos esta carga, recopilamos los picos diarios, los multiplicamos por diez y eso se convirti\u00f3 en nuestro l\u00edmite de tasa. Estamos siempre atentos. A menudo vemos bots y esc\u00e1neres que intentan verificar si tenemos alg\u00fan script CGA que puedan ejecutar, y los cortamos activamente.<\/p>\n<h2>C\u00f3mo actualizar la base de c\u00f3digo sin que los usuarios se den cuenta<\/h2>\n<p>\nImplementamos la tolerancia a fallos tambi\u00e9n a nivel de los procesos de despliegue de c\u00f3digo. En las implementaciones pueden ocurrir fallos, pero su impacto en la disponibilidad de los servicios se puede minimizar.<\/p>\n<p>Actualizamos constantemente nuestros servicios y debemos garantizar el proceso de actualizaci\u00f3n de la base de c\u00f3digo sin afectar a los usuarios. Esta tarea se resolvi\u00f3 utilizando las capacidades de gesti\u00f3n de HAProxy y la implementaci\u00f3n de Graceful Shutdown en nuestros servicios.<\/p>\n<p>Para resolver esta tarea, era necesario gestionar el equilibrador de carga y realizar un apagado \u2018correcto\u2019 de los servicios:<\/p>\n<ul>\n<li>En el caso de HAProxy, la gesti\u00f3n se lleva a cabo a trav\u00e9s del archivo stats, que esencialmente es un socket y se define en la configuraci\u00f3n de HAProxy. Se pueden enviarle comandos a trav\u00e9s de stdio. Pero nuestra herramienta principal de control de configuraciones es ansible, por lo que tiene un m\u00f3dulo incorporado para gestionar HAProxy, el cual utilizamos activamente. <\/li>\n<li>La mayor parte de nuestros servicios API y Engine admiten tecnolog\u00edas de apagado ordenado: al apagarse, esperan a que finalice la tarea actual, ya sea una solicitud HTTP o alguna tarea de servicio. Lo mismo ocurre con el worker. \u00c9l conoce todas las tareas que est\u00e1 realizando y se detiene cuando ha completado todo con \u00e9xito. <\/li>\n<\/ul>\n<p>\nGracias a estos dos aspectos, el algoritmo seguro de nuestro despliegue se ve de la siguiente manera.<\/p>\n<ol>\n<li>El desarrollador compila un nuevo paquete de c\u00f3digo (en nuestro caso es RPM), lo prueba en un entorno de desarrollo, lo prueba en stage y lo deja en el repositorio de stage.<\/li>\n<li>El desarrollador establece la tarea para el despliegue con una descripci\u00f3n detallada de los \u00abartefactos\u00bb: versi\u00f3n del nuevo paquete, descripci\u00f3n de nuevas funcionalidades y otros detalles sobre el despliegue si es necesario.<\/li>\n<li>El administrador del sistema comienza la actualizaci\u00f3n. Inicia el playbook de Ansible, que a su vez hace lo siguiente: \n<ul>\n<li>Toma el paquete del repositorio de stage, y actualiza la versi\u00f3n del paquete en el repositorio de producci\u00f3n.<\/li>\n<li>Compila una lista de los backends del servicio que se est\u00e1 actualizando.<\/li>\n<li>Desactiva el primer servicio que se est\u00e1 actualizando en HAProxy y espera a que finalicen sus procesos. Gracias al apagado gracioso, nos aseguramos de que todas las solicitudes actuales de los clientes se completen con \u00e9xito.<\/li>\n<li>Despu\u00e9s de la detenci\u00f3n completa del API, los workers y la desactivaci\u00f3n de HAProxy, se produce la actualizaci\u00f3n del c\u00f3digo.<\/li>\n<li>Ansible inicia los servicios.<\/li>\n<li>Para cada servicio, activa ciertos \u00abdisparadores\u00bb, que realizan pruebas unitarias seg\u00fan una serie de pruebas clave predefinidas. Se realiza una verificaci\u00f3n b\u00e1sica del nuevo c\u00f3digo.<\/li>\n<li>Si no se encontraron errores en el paso anterior, se activa el backend.<\/li>\n<li>Pasamos al siguiente backend.<\/li>\n<\/ul>\n<\/li>\n<li>Despu\u00e9s de actualizar todos los backends, se ejecutan pruebas funcionales. Si no son suficientes, el desarrollador revisa cualquier nueva funcionalidad que haya implementado.<\/li>\n<\/ol>\n<p>\nEn este punto, el despliegue se ha completado.<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo se implementa una arquitectura web resistente a fallos en la plataforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/2d889fe1af33653e4bfebabe1cce6552.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Ciclo de actualizaci\u00f3n del servicio<\/i><\/p>\n<p>Este esquema no funcionar\u00eda si no tuvi\u00e9ramos una regla. Mantenemos en producci\u00f3n simult\u00e1neamente las versiones antigua y nueva. Desde la etapa de desarrollo del software, se establece que incluso si hay cambios en la base de datos del servicio, no romper\u00e1n el c\u00f3digo anterior. Como resultado, se produce una actualizaci\u00f3n gradual de la base de c\u00f3digo.<\/p>\n<h2>Conclusi\u00f3n<\/h2>\n<p>\nCompartiendo mis propios pensamientos sobre la arquitectura WEB tolerante a fallos, quiero destacar una vez m\u00e1s sus puntos clave:<\/p>\n<ul>\n<li>tolerancia a fallos f\u00edsica;<\/li>\n<li>tolerancia a fallos de red (balanceadores, BGP);<\/li>\n<li>tolerancia a fallos del software utilizado y desarrollado.<\/li>\n<\/ul>\n<p>\n\u00a1Les deseo a todos un uptime estable!<br \/>\n<br \/>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/474180\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u042f \u0410\u0440\u0442\u0435\u043c \u041a\u0430\u0440\u0430\u043c\u044b\u0448\u0435\u0432, \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Mail.Ru Cloud Solutions (MCS). \u0417\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0433\u043e\u0434 \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 \u043d\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432. \u041c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b API-\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043b\u0435\u0433\u043a\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c, \u0431\u044b\u043b\u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u043c\u0438 \u0438 \u0433\u043e\u0442\u043e\u0432\u044b\u043c\u0438 \u043a \u0431\u044b\u0441\u0442\u0440\u043e\u043c\u0443 \u0440\u043e\u0441\u0442\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u041d\u0430\u0448\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 OpenStack, \u0438 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0437\u0430\u043a\u0440\u044b\u0442\u044c, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-52389","post","type-post","status-publish","format-standard","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=\".\" \/>\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\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions\" \/>\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\u041a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u0430\u044f \u0432\u0435\u0431-\u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0432 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Mail.ru Cloud Solutions | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\".\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions\" \/>\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-11-06T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:05+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\udd47C\u00f3mo se implementa una arquitectura web tolerante a fallos en la plataforma Mail.ru Cloud Solutions | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","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\u041a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u0430\u044f \u0432\u0435\u0431-\u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0432 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Mail.ru Cloud Solutions | ProHoster","og:description":".","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","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-11-06T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:05+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52389","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-01-24 03:27:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:44:43","updated":"2026-01-24 03:27:21","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\/52389","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=52389"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/52389\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=52389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=52389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=52389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}