Monitoreo como servicio: un sistema modular para la arquitectura de microservicios

Hoy, además del código monolítico, decenas de microservicios operan en nuestro proyecto. Cada uno de ellos requiere ser monitoreado. Es problemático hacer esto en tales volúmenes por ingenieros de DevOps. Hemos desarrollado un sistema de monitorización que funciona como un servicio para los desarrolladores. Pueden escribir métricas de forma independiente en el sistema de monitoreo, usarlas, crear tableros basados ​​en ellas, adjuntarles alertas que se activarán cuando se alcancen los valores de umbral. Con ingenieros DevOps: solo infraestructura y documentación.

Esta publicación es una transcripción de mi discurso de nuestra sección en RIT++. Muchos nos pidieron que hiciéramos versiones de texto de los informes desde allí. Si ha estado en una conferencia o ha visto un video, no encontrará nada nuevo. Y a todos los demás, bienvenidos bajo cat. Les diré cómo llegamos a tal sistema, cómo funciona y cómo planeamos actualizarlo.

Monitoreo como servicio: un sistema modular para la arquitectura de microservicios

Pasado: esquemas y planes

¿Cómo llegamos al sistema de monitoreo existente? Para responder a esta pregunta, debe ir a 2015. Esto es lo que parecía entonces:

Monitoreo como servicio: un sistema modular para la arquitectura de microservicios

Teníamos alrededor de 24 nodos que se encargaban de monitorear. Hay un montón de diferentes crons, scripts, daemons que monitorean algo en algún lugar, envían mensajes, realizan funciones. Pensamos que cuanto más lejos, menos viable sería un sistema de este tipo. No tiene sentido desarrollarlo: es demasiado engorroso.
Decidimos elegir aquellos elementos de monitoreo que dejaremos y desarrollaremos, y aquellos que abandonaremos. Eran 19. Solo quedaban grafitos, agregadores y Grafana como salpicadero. Pero, ¿cómo será el nuevo sistema? Como esto:

Monitoreo como servicio: un sistema modular para la arquitectura de microservicios

Tenemos un repositorio de métricas: estos son grafitos que se basarán en unidades SSD rápidas, estos son ciertos agregadores de métricas. Siguiente: Grafana para mostrar paneles y Moira como alerta. También queríamos desarrollar un sistema para encontrar anomalías.

Estándar: Monitoreo 2.0

Así se veían los planes en 2015. Pero tuvimos que preparar no solo la infraestructura y el servicio en sí, sino también la documentación para ello. Hemos desarrollado un estándar corporativo para nosotros mismos, al que llamamos monitoreo 2.0. ¿Cuáles eran los requisitos para el sistema?

  • disponibilidad constante;
  • intervalo de almacenamiento de métricas = 10 segundos;
  • almacenamiento estructurado de métricas y tableros;
  • ANS > 99,99 %
  • recopilación de métricas de eventos a través de UDP (!).

Necesitábamos UDP porque tenemos mucho tráfico y eventos que generan métricas. Si están todos escritos en grafito a la vez, el repositorio colapsará. También elegimos prefijos de primer nivel para todas las métricas.

Monitoreo como servicio: un sistema modular para la arquitectura de microservicios

Cada uno de los prefijos tiene alguna propiedad. Hay métricas para servidores, redes, contenedores, recursos, aplicaciones, etc. Se implementó un filtrado claro, estricto y tipificado, en el que aceptamos las métricas de primer nivel y simplemente descartamos el resto. Así planificamos este sistema en 2015. ¿Qué hay en el presente?

Presente: el esquema de interacción de los componentes de monitoreo.

En primer lugar, supervisamos las aplicaciones: nuestro código PHP, aplicaciones y microservicios; en una palabra, todo lo que escriben nuestros desarrolladores. Todas las aplicaciones envían métricas a través de UDP al agregador de Brubeck (statsd, reescrito en C). Resultó ser el más rápido según los resultados de las pruebas sintéticas. Y envía las métricas ya agregadas a Graphite a través de TCP.

Tiene ese tipo de métricas como temporizadores. Esto es algo muy útil. Por ejemplo, para cada conexión de usuario al servicio, envía una métrica de tiempo de respuesta a Brubeck. Llegaron un millón de respuestas y el agregador entregó solo 10 métricas. Tienes el número de personas que acudieron, los tiempos de respuesta máximo, mínimo y medio, la mediana y 4 percentiles. Luego, los datos se transfieren a Graphite y los vemos todos en vivo.

También tenemos agregación de hardware, software, métricas del sistema y nuestro antiguo sistema de monitoreo Munin (funcionó con nosotros hasta 2015). Recopilamos todo esto a través del demonio C'ish CollectD (se cosen un montón de varios complementos, puede consultar todos los recursos del sistema host en el que está instalado, solo especifique en la configuración dónde escribir datos ) y escribir datos a través de él en Graphite. También admite complementos de python y scripts de shell, por lo que puede escribir sus propias soluciones personalizadas: CollectD recopilará estos datos de un host local o remoto (suponiendo que Curl esté disponible) y los enviará a Graphite.

Además, todas las métricas que hemos recopilado se envían a Carbon-c-relay. Esta es la solución Carbon Relay de Graphite, modificada en C. Este es un enrutador que recopila todas las métricas que enviamos desde nuestros agregadores y las enruta a través de los nodos. También en la etapa de enrutamiento, verifica la validez de las métricas. En primer lugar, deben coincidir con el esquema de prefijos que mostré anteriormente y, en segundo lugar, deben ser válidos para el grafito. De lo contrario, se caen.

Luego, Carbon-c-relay envía las métricas al clúster Graphite. Usamos Carbon-cache reescrito en Go como almacenamiento principal para las métricas. Go-carbon, debido a su subprocesamiento múltiple, es muy superior en rendimiento a Carbon-cache. Toma datos en sí mismo y los escribe en el disco usando el paquete susurro (estándar, escrito en python). Para leer datos de nuestros almacenamientos, utilizamos la API Graphite. Funciona mucho más rápido que el Graphite WEB estándar. ¿Qué sucede con los datos a continuación?

Van a Grafana. Usamos nuestros clústeres de grafito como la principal fuente de datos, además tenemos Grafana como una interfaz web para mostrar métricas y crear paneles. Para cada uno de sus servicios, los desarrolladores crean su propio tablero. Luego construyen gráficos basados ​​en ellos, que muestran las métricas que escriben desde sus aplicaciones. Además de Grafana, también tenemos SLAM. Este es un demonio pitónico que calcula SLA basado en datos de grafito. Como dije, tenemos varias docenas de microservicios, cada uno de los cuales tiene sus propios requisitos. Con la ayuda de SLAM, vamos a la documentación y la comparamos con lo que está en Graphite y comparamos cómo los requisitos corresponden a la disponibilidad de nuestros servicios.

Yendo más allá: alertando. Está organizado con un sistema fuerte - Moira. Es independiente porque tiene su propio Graphite bajo el capó. Desarrollado por los chicos de SKB Kontur, escrito en python y Go, totalmente de código abierto. Moira recibe todo el mismo caudal que entra en los grafitos. Si por alguna razón su almacenamiento muere, entonces sus alertas funcionarán.

Implementamos Moira en Kubernetes, utiliza un clúster de servidores Redis como base de datos principal. El resultado es un sistema tolerante a fallos. Compara el flujo de métricas con la lista de activadores: si no hay menciones en ella, descarta la métrica. Por lo que es capaz de digerir gigabytes de métricas por minuto.

También le agregamos un LDAP corporativo, con la ayuda de la cual cada usuario del sistema corporativo puede crear notificaciones para sí mismo sobre activadores existentes (o recién creados). Dado que Moira contiene grafito, es compatible con todas sus funciones. Entonces, primero toma la línea y la copia en Grafana. Vea cómo se muestran los datos en los gráficos. Y luego tomas la misma línea y la copias en Moira. Cuélgalo con límites y recibe una alerta en la salida. Para hacer todo esto, no necesitas ningún conocimiento específico. Moira puede alertar por SMS, correo electrónico, Jira, Slack… También admite scripts personalizados. Cuando tiene un activador y está suscrita a un script o binario personalizado, lo inicia y envía este binario JSON a la entrada estándar. En consecuencia, su programa debe analizarlo. Lo que hará con este JSON depende de usted. Si quieres envíalo a Telegram, si quieres abre tareas en Jira, haz lo que quieras.

También utilizamos nuestro propio desarrollo para alertar: Imagotag. Adaptamos el panel, que se suele utilizar para las etiquetas de precios electrónicas en las tiendas, a nuestras necesidades. Le trajimos disparadores de Moira. Indica en qué condición se encuentran, cuándo sucedieron. Algunos de los chicos del desarrollo abandonaron las notificaciones en Slack y en el correo a favor de este panel.

Monitoreo como servicio: un sistema modular para la arquitectura de microservicios

Bueno, dado que somos una empresa progresista, también monitoreamos Kubernetes en este sistema. Incluido en el sistema usando Heapster, que instalamos en el clúster, recopila datos y los envía a Graphite. Como resultado, el esquema se ve así:

Monitoreo como servicio: un sistema modular para la arquitectura de microservicios

Componentes de monitoreo

Aquí hay una lista de enlaces a los componentes que usamos para esta tarea. Todos ellos son de código abierto.

Grafito:

Relé de carbono-c:

github.com/grobian/carbon-c-relé

Brubeck:

github.com/github/brubeck

Recogido:

recopilad.org

moira:

github.com/moira-alerta

Grafana:

grafana.com

montón:

github.com/kubernetes/heapster

Estadísticas

Y aquí hay algunos números sobre cómo funciona el sistema para nosotros.

Agregador (brubeck)

Número de métricas: ~ 300 / seg
Intervalo de envío de métricas de grafito: 30 segundos
Utilización de recursos del servidor: ~ 6% de CPU (estamos hablando de servidores completos); ~ 1 GB de RAM; ~ LAN de 3 Mbps

Grafito (go-carbono)

Número de métricas: ~ 1 / min
Intervalo de actualización de métricas: 30 segundos
Esquema de almacenamiento de métricas: 30 s 35 d, 5 min 90 d, 10 min 365 d (da una idea de lo que sucede con el servicio durante un largo período de tiempo)
Uso de recursos del servidor: ~10 % de CPU; ~ 20 GB de RAM; ~ LAN de 30 Mbps

Flexibilidad

En Avito realmente apreciamos la flexibilidad de nuestro servicio de monitoreo. ¿Por qué en realidad resultó así? Primero, sus partes constituyentes son intercambiables: tanto los propios componentes como sus versiones. En segundo lugar, la mantenibilidad. Dado que todo el proyecto se basa en código abierto, puede editar el código usted mismo, realizar cambios e implementar funciones que no están disponibles de forma inmediata. Se utilizan pilas bastante comunes, principalmente Go y Python, por lo que esto se hace de manera bastante simple.

Aquí hay un ejemplo de un problema real. Una métrica en Graphite es un archivo. tiene un nombre Nombre de archivo = nombre de la métrica. Y hay una manera de llegar allí. Los nombres de archivo en Linux están limitados a 255 caracteres. Y tenemos (como "clientes internos") chicos del departamento de base de datos. Nos dicen: “Queremos monitorear nuestras consultas SQL. Y no son 255 caracteres, sino 8 MB cada uno. Queremos mostrarlos en Grafana, ver los parámetros de esta solicitud y, aún mejor, queremos ver la parte superior de dichas solicitudes. Será genial si se muestra en tiempo real. Y sería genial ponerlos en alerta”.

Monitoreo como servicio: un sistema modular para la arquitectura de microservicios
El ejemplo de consulta SQL se toma como ejemplo de sitio postgrespro.ru

Subimos el servidor Redis y nuestros complementos Collectd que van a Postgres y toman todos los datos de allí, envían métricas a Graphite. Pero reemplazamos el nombre de la métrica con hashes. El mismo hash se envía simultáneamente a Redis como clave y la consulta SQL completa como valor. Nos queda hacer que Grafana pueda ir a Redis y tomar esta información. Estamos abriendo la API Graphite porque esta es la interfaz principal para la interacción de todos los componentes de monitoreo con grafito, e ingresamos una nueva función allí llamada aliasByHash (): obtenemos el nombre de la métrica de Grafana y la usamos en una solicitud a Redis como clave, en respuesta obtenemos el valor de la clave, que es nuestra "consulta SQL". Así, trajimos a Grafana la visualización de una consulta SQL, que en teoría no se podría visualizar allí, junto con las estadísticas sobre la misma (llamadas, filas, tiempo_total,...).

resultados

Disponibilidad. Nuestro servicio de monitoreo está disponible 24/7 desde cualquier aplicación y cualquier código. Si tiene acceso a los almacenamientos, puede escribir datos en el servicio. El lenguaje no es importante, las decisiones no son importantes. Solo necesita saber cómo abrir un socket, lanzar una métrica allí y cerrar el socket.

Confiabilidad. Todos los componentes son tolerantes a fallas y manejan bien nuestras cargas de trabajo.

Bajo umbral de entrada. Para poder utilizar este sistema, no es necesario aprender lenguajes de programación y consultas en Grafana. Simplemente abra su aplicación, agréguele un socket que enviará métricas a Graphite, ciérrela, abra Grafana, cree tableros allí y observe el comportamiento de sus métricas, recibiendo notificaciones a través de Moira.

Independencia. Puede hacer todo esto usted mismo, sin la ayuda de ingenieros de DevOps. Y esta es una característica adicional, porque puede monitorear su proyecto en este momento, no tiene que preguntarle a nadie, ni para comenzar a trabajar ni para hacer cambios.

¿A qué apuntamos?

Todo lo que se enumera a continuación no son solo pensamientos abstractos, sino algo hacia lo que al menos se han dado los primeros pasos.

  1. detector de anomalías. Queremos crear un servicio que vaya a nuestros almacenamientos de Graphite y verifique cada métrica usando varios algoritmos. Ya hay algoritmos que queremos ver, hay datos, sabemos cómo trabajar con ellos.
  2. metadatos Tenemos muchos servicios, van cambiando con el tiempo, así como las personas que trabajan con ellos. Mantener registros manualmente no es una opción. Por lo tanto, los metadatos ahora están integrados en nuestros microservicios. Indica quién lo desarrolló, los idiomas con los que interactúa, los requisitos de SLA, dónde y a quién enviar notificaciones. Al implementar un servicio, todos los datos de la entidad se crean de forma independiente. Como resultado, obtiene dos enlaces: uno para activadores y otro para paneles en Grafana.
  3. Monitoreo en cada hogar. Creemos que todos los desarrolladores deberían usar un sistema de este tipo. En este caso, siempre entiendes dónde está tu tráfico, qué le sucede, dónde cae, dónde tiene puntos débiles. Si, por ejemplo, algo llega y bloquea su servicio, no se enterará durante una llamada del administrador, sino a través de una alerta, y podrá abrir registros nuevos de inmediato y ver qué sucedió allí.
  4. Alto rendimiento. Nuestro proyecto está en constante crecimiento, y hoy en día procesa alrededor de 2 de valores métricos por minuto. Hace un año, esta cifra era de 000 000. Y el crecimiento continúa, y esto significa que después de un tiempo, Graphite (susurro) comenzará a cargar mucho el subsistema del disco. Como dije, este sistema de monitoreo es bastante versátil debido a la intercambiabilidad de los componentes. Alguien específicamente para Graphite mantiene y expande constantemente su infraestructura, pero decidimos ir por el otro lado: usar casa de clics como repositorio de nuestras métricas. Esta transición está casi completa, y muy pronto les contaré con más detalle cómo se hizo: cuáles fueron las dificultades y cómo se superaron, cómo fue el proceso de migración, describiré los componentes seleccionados como vinculantes y sus configuraciones.

¡Gracias por su atención! Haga sus preguntas sobre el tema, trataré de responder aquí o en las siguientes publicaciones. Tal vez alguien tenga experiencia en la construcción de un sistema de monitoreo similar o en cambiar a Clickhouse en una situación similar; compártalo en los comentarios.

Fuente: habr.com

Añadir un comentario