Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Andrey Nikolsky, director de operaciones del portal Banki.ru, habló en la conferencia del año pasado DevOpsDays Moscú sobre servicios huérfanos: cómo identificar a un huérfano en la infraestructura, por qué los servicios huérfanos son malos, qué hacer con ellos y qué hacer si nada ayuda.

Debajo del corte hay una versión de texto del informe.


¡Hola colegas! Mi nombre es Andrey, dirijo las operaciones en Banki.ru.

Tenemos grandes servicios, estos son servicios tan monolíticos, hay servicios en un sentido más clásico y los hay muy pequeños. En mi terminología obrero-campesina, digo que si un servicio es simple y pequeño, entonces es micro, y si no es muy simple y pequeño, entonces es sólo un servicio.

Ventajas de los servicios

Repasaré rápidamente las ventajas de los servicios.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

El primero es escalar. Puede hacer algo rápidamente en el servicio e iniciar la producción. Has recibido tráfico, has clonado el servicio. Tienes más tráfico, lo has clonado y vives con él. Esta es una buena ventaja y, en principio, cuando empezamos, lo más importante para nosotros era considerar por qué hacíamos todo esto.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

En segundo lugar, el desarrollo aislado, cuando tienes varios equipos de desarrollo, varios desarrolladores diferentes en cada equipo y cada equipo desarrolla su propio servicio.

Con los equipos hay un matiz. Los desarrolladores son diferentes. Y hay, por ejemplo, gente copo de nieve. La primera vez que vi esto fue con Maxim Dorofeev. A veces, los copos de nieve están en algunos equipos y en otros no. Esto hace que los diferentes servicios utilizados en la empresa sean un poco desiguales.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Mire la imagen: este es un buen desarrollador, tiene manos grandes, puede hacer mucho. El principal problema es de dónde vienen estas manos.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Los servicios permiten utilizar diferentes lenguajes de programación que son más adecuados para diferentes tareas. Algunos servicios están en Go, otros en Erlang, otros en Ruby, otros en PHP y otros en Python. En general, puedes expandirte mucho. Aquí también hay matices.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

La arquitectura orientada a servicios se trata principalmente de devops. Es decir, si no tienes automatización, no hay proceso de implementación, si lo configuras manualmente, tus configuraciones pueden cambiar de una instancia de servicio a otra y tienes que ir allí para hacer algo, entonces estás en el infierno.

Por ejemplo, tienes 20 servicios y necesitas implementarlos manualmente, tienes 20 consolas y simultáneamente presionas “enter” como un ninja. No es muy bueno.

Si tienes un servicio después de probarlo (si hay pruebas, claro), y aún necesitas terminarlo con un archivo para que funcione en producción, también tengo malas noticias para ti.

Si confía en servicios específicos de Amazon y trabaja en Rusia, hace dos meses también dijo: "Todo a mi alrededor está en llamas, estoy bien, todo está bien".

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Usamos Ansible para automatizar la implementación, Puppet para la convergencia, Bamboo para automatizar la implementación y Confluence para describirlo todo de alguna manera.

No me detendré en esto en detalle, porque el informe trata más sobre prácticas de interacción y no sobre implementación técnica.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Por ejemplo, hemos tenido problemas cuando Puppet en el servidor funciona con Ruby 2, pero algunas aplicaciones están escritas para Ruby 1.8 y no funcionan juntas. Algo sale mal ahí. Y cuando necesitas ejecutar varias versiones de Ruby en una máquina, normalmente empiezas a tener problemas.

Por ejemplo, le damos a cada desarrollador una plataforma en la que está aproximadamente todo lo que tenemos, todos los servicios que se pueden desarrollar, para que tenga un entorno aislado, pueda descomponerlo y construirlo como quiera.

Sucede que necesita algún paquete especialmente compilado que admita algo allí. Es bastante duro. Escuché un informe donde la imagen de Docker pesa 45 GB. En Linux, por supuesto, es más sencillo, allí todo es más pequeño, pero aun así no habrá suficiente espacio.

Bueno, hay dependencias en conflicto, cuando una parte del proyecto depende de una biblioteca de una versión, otra parte del proyecto depende de otra versión y las bibliotecas no se instalan juntas en absoluto.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Tenemos sitios y servicios en PHP 5.6, nos da vergüenza, pero ¿qué podemos hacer? Este es nuestro único sitio. Hay sitios y servicios en PHP 7, hay más, no nos avergonzamos de ellos. Y cada desarrollador tiene su propia base donde ve felizmente.

Si en una empresa se escribe en un idioma, entonces tres máquinas virtuales por desarrollador parece normal. Si tienes diferentes lenguajes de programación, la situación empeora.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Tiene sitios y servicios en este, en este, luego otro sitio para Go, un sitio para Ruby y algún otro Redis al lado. Como resultado, todo esto se convierte en un gran campo de apoyo, y todo el tiempo una parte puede romperse.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Por lo tanto, reemplazamos los beneficios del lenguaje de programación con el uso de diferentes frameworks, ya que los frameworks PHP son bastante diferentes, tienen diferentes capacidades, diferentes comunidades y diferentes soportes. Y puedes escribir un servicio para que ya tengas algo listo para él.

Cada servicio tiene su propio equipo.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Nuestra principal ventaja, que se ha cristalizado a lo largo de varios años, es que cada servicio cuenta con su propio equipo. Esto es conveniente para un proyecto grande, puede ahorrar tiempo en la documentación y los gerentes conocen bien su proyecto.

Puede enviar tareas fácilmente desde el soporte. Por ejemplo, el servicio de seguros se averió. E inmediatamente el equipo que se ocupa de los seguros va a arreglarlo.

Se están creando rápidamente nuevas funciones, porque cuando tienes un servicio atómico, puedes incorporarle algo rápidamente.

Y cuando interrumpes tu servicio, y esto sucede inevitablemente, no afectaste los servicios de otras personas, y los desarrolladores de otros equipos no vienen corriendo hacia ti con bits y te dicen: "Sí, no hagas eso".

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Como siempre, hay matices. Tenemos equipos estables, los directivos están clavados al equipo. Hay documentos claros, los gerentes siguen todo de cerca. Cada equipo con un gerente tiene varios servicios y hay un punto de competencia específico.

Si los equipos están flotando (a veces también usamos esto), existe un buen método llamado "mapa estelar".

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Tienes una lista de servicios y personas. Un asterisco significa que la persona es experta en este servicio, un libro significa que la persona está estudiando este servicio. La tarea de la persona es cambiar el folleto por un asterisco. Y si no hay nada escrito delante del servicio, entonces comienzan los problemas, de los que hablaré más adelante.

¿Cómo aparecen los servicios para huérfanos?

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

El primer problema, la primera forma de conseguir un servicio huérfano en su infraestructura es despedir gente. ¿Alguien ha tenido alguna vez una empresa que cumpliera con los plazos antes de evaluar las tareas? A veces sucede que los plazos son ajustados y simplemente no hay tiempo suficiente para la documentación. "Necesitamos entregar el servicio a producción y luego lo agregaremos".

Si el equipo es pequeño, sucede que hay un desarrollador que escribe todo, el resto está entre bastidores. "Escribí la arquitectura básica, agreguemos las interfaces". Luego, en algún momento, el gerente, por ejemplo, se marcha. Y durante este período, cuando el gerente se ha ido y aún no se ha nombrado uno nuevo, los propios desarrolladores deciden hacia dónde va el servicio y qué sucede allí. Y como sabemos (regresemos algunas diapositivas), en algunos equipos hay personas copo de nieve, a veces un líder de equipo copo de nieve. Luego renuncia y recibimos un servicio para huérfanos.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Al mismo tiempo, las tareas de soporte y de negocio no desaparecen, sino que acaban en el backlog. Si hubo algún error arquitectónico durante el desarrollo del servicio, también termina en el backlog. El servicio se está deteriorando lentamente.

¿Cómo identificar a un huérfano?

Esta lista describe bien la situación. ¿Quién aprendió algo sobre su infraestructura?

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Sobre soluciones documentadas: hay un servicio y, en general, funciona, tiene un manual de dos páginas sobre cómo trabajar con él, pero nadie sabe cómo funciona por dentro.

O, por ejemplo, existe algún tipo de acortador de enlaces. Por ejemplo, actualmente utilizamos tres acortadores de enlaces para diferentes propósitos en diferentes servicios. Estas son sólo las consecuencias.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Ahora seré el capitán de lo obvio. ¿Lo que debe hacerse? Primero, necesitamos transferir el servicio a otro gerente, a otro equipo. Si el líder de su equipo aún no ha renunciado, entonces en este otro equipo, cuando comprenda que el servicio es huérfano, debe incluir a alguien que entienda al menos algo al respecto.

Lo principal: debes tener los procedimientos de transferencia escritos con sangre. En nuestro caso, suelo controlar esto porque necesito que todo funcione. Los gerentes necesitan que se entregue rápidamente y lo que suceda después ya no es tan importante para ellos.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

La siguiente forma de convertirlo en huérfano es: "Lo haremos subcontratado, será más rápido y luego se lo entregaremos al equipo". Está claro que todos tienen unos planes en el equipo, un turno. Muchas veces un cliente empresarial piensa que el subcontratista hará lo mismo que el departamento técnico que tiene la empresa. Aunque sus motivadores son diferentes. Hay soluciones tecnológicas extrañas y soluciones algorítmicas extrañas en la subcontratación.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Por ejemplo, teníamos un servicio que tenía Sphinx en varios lugares inesperados. Más adelante os contaré lo que tuve que hacer.

Los subcontratistas tienen marcos escritos por ellos mismos. Esto es simplemente PHP con copiar y pegar de un proyecto anterior, donde puedes encontrar todo tipo de cosas. Los scripts de implementación son un gran inconveniente cuando necesitas usar algunos scripts Bash complejos para cambiar varias líneas en algún archivo, y estos scripts de implementación son llamados por un tercer script. Como resultado, cambia el sistema de implementación, elige otra cosa, salta, pero su servicio no funciona. Porque ahí era necesario poner 8 enlaces más entre diferentes carpetas. O sucede que mil discos funcionan, pero cien mil ya no funcionan.

Seguiré siendo capitán. Aceptar un servicio subcontratado es un trámite obligatorio. ¿A alguien le ha llegado alguna vez un servicio subcontratado y no ha sido aceptado en ningún lado? Por supuesto, esto no es tan popular como un servicio huérfano, pero aún así.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Es necesario verificar el servicio, revisar el servicio, cambiar las contraseñas. Tuvimos un caso en el que nos dieron un servicio, hay un panel de administración "if login == 'admin' && contraseña == 'admin'...", está escrito directamente en el código. Nos sentamos y pensamos, ¿y la gente escribe esto en 2018?

También es necesario probar la capacidad de almacenamiento. Debe observar lo que sucederá en cien mil registros, incluso antes de poner este servicio en producción en algún lugar.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

No debería avergonzarse de enviar un servicio para mejorarlo. Cuando dices: "No aceptaremos este servicio, tenemos 20 tareas, hazlas y luego aceptaremos", esto es normal. No debe dolerle su conciencia el hecho de que esté contratando un administrador o que la empresa esté desperdiciando dinero. Entonces la empresa gastará más.

Tuvimos un caso en el que decidimos subcontratar un proyecto piloto.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Se entregó a tiempo y este fue el único criterio de calidad. Por eso hicimos otro proyecto piloto, que ya ni siquiera era un piloto. Estos servicios fueron aceptados, y por vía administrativa dijeron, aquí está tu código, aquí está el equipo, aquí está tu manager. De hecho, los servicios ya han comenzado a generar beneficios. Al mismo tiempo, de hecho, siguen siendo huérfanos, nadie entiende cómo trabajan y los directivos hacen todo lo posible por repudiar sus tareas.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Hay otro gran concepto: el desarrollo guerrillero. Cuando algún departamento, normalmente el de marketing, quiere probar una hipótesis y encarga la subcontratación de todo el servicio. Empieza a llegar tráfico, cierran los documentos, firman documentos con el contratista, entran en funcionamiento y dicen: “Amigos, aquí tenemos un servicio, ya tiene tráfico, nos trae dinero, aceptémoslo”. Pensamos: "Oppa, ¿cómo puede ser eso?".

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Y otra forma de obtener un servicio huérfano: cuando algún equipo de repente se encuentra cargado, la gerencia dice: "Transfiramos el servicio de este equipo a otro equipo, tiene una carga menor". Y luego lo transferiremos a un tercer equipo y cambiaremos de entrenador. Y al final volvemos a tener un huérfano.

¿Cuál es el problema con los huérfanos?

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Quién no lo sabe, este es el acorazado Wasa levantado en Suecia, famoso por el hecho de que se hundió 5 minutos después del lanzamiento. Y el rey de Suecia, por cierto, no ejecutó a nadie por esto. Fue construido por dos generaciones de ingenieros que no sabían cómo construir tales barcos. Efecto natural.

Por cierto, el barco podría haberse hundido de una manera mucho peor, por ejemplo, cuando el rey ya viajaba en él en algún lugar de una tormenta. Y así, se ahogó de inmediato; según Agile, es bueno fallar temprano.

Si fallamos temprano, normalmente no hay problemas. Por ejemplo, durante la aceptación se envió para revisión. Pero si ya fallamos en la producción, cuando se invierte dinero, entonces puede haber problemas. Consecuencias, como se les llama en los negocios.

Por qué los servicios huérfanos son peligrosos:

  • El servicio puede interrumpirse repentinamente.
  • El servicio tarda mucho en repararse o no se repara en absoluto.
  • Problemas de seguridad.
  • Problemas con mejoras y actualizaciones.
  • Si un servicio importante falla, la reputación de la empresa se ve afectada.

¿Qué hacer con los servicios para huérfanos?

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Repetiré qué hacer nuevamente. Primero, debe haber documentación. 7 años en Banki.ru me enseñaron que los evaluadores no deben confiar en la palabra de los desarrolladores y que las operaciones no deben confiar en la palabra de todos. Necesitamos comprobarlo.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

En segundo lugar, es necesario escribir diagramas de interacción, porque sucede que servicios que no son muy bien recibidos contienen dependencias de las que nadie habló. Por ejemplo, los desarrolladores instalaron el servicio en su clave para algunos Yandex.Maps o Dadata. Se te acabó el límite gratuito, todo está roto y no sabes en absoluto qué pasó. Todos estos rastrillos deben describirse: el servicio utiliza Dadata, SMS y algo más.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

En tercer lugar, trabajar con deuda técnica. Cuando haces algún tipo de muletas o aceptas un servicio y dices que hay que hacer algo, debes asegurarte de que se haga. Porque entonces puede resultar que el pequeño agujero no sea tan pequeño y te caigas por él.

Con las tareas arquitectónicas, teníamos una historia sobre la Esfinge. Uno de los servicios utilizó Sphinx para ingresar listas. Sólo una lista paginada, pero se reindexaba cada noche. Se ensamblaba a partir de dos índices: cada noche se indexaba uno grande y también había un índice pequeño que se atornillaba a él. Todos los días, con un 50% de probabilidad de bombardeo o no, el índice colapsaba durante el cálculo y nuestras noticias dejaban de actualizarse en la página principal. Al principio, el índice tardó 5 minutos en volver a indexarse, luego el índice creció y, en algún momento, empezó a tardar 40 minutos en volver a indexarse. Cuando eliminamos esto, respiramos aliviados, porque estaba claro que pasaría un poco más de tiempo y nuestro índice se volvería a indexar a tiempo completo. Esto será un fracaso para nuestro portal, no habrá noticias durante ocho horas, eso es todo, el negocio se detuvo.

Plan para trabajar con un servicio huérfano

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

De hecho, esto es muy difícil de hacer, porque Devops se trata de comunicación. Quiere estar en buenos términos con sus colegas, y cuando golpea a sus colegas y gerentes con regulaciones, es posible que tengan sentimientos encontrados hacia las personas que hacen esto.

Además de todos estos puntos, hay otra cosa importante: personas específicas deben ser responsables de cada servicio específico, de cada sección específica del procedimiento de implementación. Cuando no hay gente y hay que atraer a otras personas para que estudien todo este asunto, se vuelve difícil.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Si todo esto no ayudó y su servicio huérfano sigue siendo huérfano, nadie quiere hacerse cargo de él, la documentación no está escrita, el equipo que fue llamado a este servicio se niega a hacer nada, hay una manera simple: rehacer todo.

Es decir, se toman de nuevo los requisitos del servicio y se escribe un servicio nuevo, mejor, en una plataforma mejor, sin soluciones tecnológicas extrañas. Y migras hacia él en la batalla.

Servicios huérfanos: la desventaja de la arquitectura de (micro)servicios

Tuvimos una situación en la que tomamos un servicio en Yii 1 y nos dimos cuenta de que no podíamos desarrollarlo más porque nos quedamos sin desarrolladores que pudieran escribir bien en Yii 1. Todos los desarrolladores escriben bien en Symfony XNUMX. ¿Qué hacer? Asignamos tiempo, asignamos un equipo, asignamos un gerente, reescribimos el proyecto y cambiamos el tráfico hacia él sin problemas.

Después de esto, se puede eliminar el servicio anterior. Este es mi procedimiento favorito, cuando necesitas tomar y limpiar algún servicio del sistema de gestión de configuración y luego revisarlo y ver que todos los autos en producción han sido desactivados, para que a los desarrolladores no les quede ningún rastro. El repositorio permanece en Git.

Esto es de lo que quería hablar, estoy listo para discutir, el tema es holívar, muchos han nadado en él.

Las diapositivas decían que unificasteis los idiomas. Un ejemplo fue el cambio de tamaño de las imágenes. ¿Es realmente necesario limitarlo estrictamente a un idioma? Porque el cambio de tamaño de la imagen en PHP, bueno, en realidad se podría hacer en Golang.

De hecho, es opcional, como todas las prácticas. Quizás, en algunos casos, esto sea incluso indeseable. Pero debes entender que si tienes un departamento técnico en una empresa de 50 personas, 45 de ellas son especialistas en PHP, otros 3 son devops que saben Python, Ansible, Puppet y algo así, y solo uno de ellos escribe en algún tipo de lenguaje Algún servicio de cambio de tamaño de imágenes Go, luego, cuando se va, la experiencia se va con él. Y al mismo tiempo, deberá buscar un desarrollador específico para el mercado que conozca este idioma, especialmente si es poco común. Es decir, desde un punto de vista organizativo, esto es problemático. Desde el punto de vista de Devops, no sólo necesitará clonar un conjunto de guías ya preparadas que utiliza para implementar servicios, sino que tendrá que volver a escribirlas.

Actualmente estamos creando un servicio en Node.js, y será solo una plataforma cercana para cada desarrollador con un idioma independiente. Pero nos sentamos y pensamos que el juego valía la pena. Es decir, esta es una pregunta en la que debes sentarte y pensar.

¿Cómo monitoreas tus servicios? ¿Cómo se recopilan y monitorean los registros?

Recopilamos registros en Elasticsearch y los colocamos en Kibana y, dependiendo de si se trata de entornos de producción o de prueba, se utilizan diferentes recopiladores allí. En algún lugar Lumberjack, en otro lugar, algo más, no lo recuerdo. Y todavía hay algunos lugares en ciertos servicios donde instalamos Telegraf y filmamos en otro lugar por separado.

¿Cómo convivir con Puppet y Ansible en un mismo entorno?

De hecho, ahora tenemos dos entornos, uno es Puppet y el otro es Ansible. Estamos trabajando para hibridarlos. Ansible es un buen marco para la configuración inicial, Puppet es un mal marco para la configuración inicial porque requiere trabajo práctico directamente en la plataforma y Puppet garantiza la convergencia de la configuración. Esto significa que la plataforma se mantiene en un estado actualizado y, para que la máquina ansibilizada se mantenga actualizada, es necesario ejecutar libros de jugadas en ella todo el tiempo con cierta frecuencia. Esa es la diferencia.

¿Cómo se mantiene la compatibilidad? ¿Tiene configuraciones tanto en Ansible como en Puppet?

Este es nuestro gran dolor, mantenemos la compatibilidad con nuestras manos y pensamos en cómo salir de todo esto en alguna parte ahora. Resulta que Puppet implementa paquetes y mantiene algunos enlaces allí, y Ansible, por ejemplo, implementa el código y ajusta las últimas configuraciones de la aplicación allí.

La presentación versó sobre diferentes versiones de Ruby. ¿Qué solución?

Nos encontramos con esto en un lugar y tenemos que tenerlo en mente todo el tiempo. Simplemente desactivamos la parte que se ejecutaba en Ruby que era incompatible con las aplicaciones y la mantuvimos separada.

La conferencia de este año DevOpsDays Moscú tendrá lugar el 7 de diciembre en Tecnópolis. Estamos aceptando solicitudes de informes hasta el 11 de noviembre. Escribir nosotros si quieres hablar.

La inscripción para participantes está abierta, ¡únete a nosotros!

Fuente: habr.com

Añadir un comentario