Monitoring as a Service: Ein modulares System für die Microservice-Architektur

Heute arbeiten neben dem monolithischen Code Dutzende von Microservices an unserem Projekt. Jeder von ihnen muss überwacht werden. Es ist problematisch, dies in solchen Mengen durch DevOps-Ingenieure durchzuführen. Wir haben ein Überwachungssystem entwickelt, das als Service für Entwickler funktioniert. Sie können selbständig Metriken in das Überwachungssystem schreiben, sie verwenden, darauf basierende Dashboards erstellen und ihnen Warnungen hinzufügen, die bei Erreichen von Schwellenwerten ausgelöst werden. Mit DevOps-Ingenieuren – nur Infrastruktur und Dokumentation.

Dieser Beitrag ist eine Abschrift meiner Rede von unserem Abschnitt auf RIT++. Viele baten uns, von dort aus Textversionen der Berichte zu erstellen. Wenn Sie auf einer Konferenz waren oder sich ein Video angesehen haben, werden Sie nichts Neues finden. Und an alle anderen – willkommen unter Katze. Ich erzähle Ihnen, wie wir zu einem solchen System gekommen sind, wie es funktioniert und wie wir es aktualisieren wollen.

Monitoring as a Service: Ein modulares System für die Microservice-Architektur

Vergangenheit: Pläne und Pläne

Wie sind wir zum bestehenden Überwachungssystem gekommen? Um diese Frage zu beantworten, müssen Sie bis 2015 gehen. So sah es damals aus:

Monitoring as a Service: Ein modulares System für die Microservice-Architektur

Wir hatten etwa 24 Knoten, die für die Überwachung verantwortlich waren. Es gibt eine ganze Reihe verschiedener Crons, Skripte und Daemons, die irgendwo etwas überwachen, Nachrichten senden und Funktionen ausführen. Wir dachten, je weiter entfernt, desto weniger lebensfähig wäre ein solches System. Es macht keinen Sinn, es zu entwickeln: Es ist zu umständlich.
Wir haben beschlossen, diejenigen Elemente der Überwachung auszuwählen, die wir aufgeben und weiterentwickeln werden, und diejenigen, die wir aufgeben werden. Es gab 19 davon. Nur Graphite, Aggregatoren und Grafana als Dashboard blieben übrig. Doch wie wird das neue System aussehen? So:

Monitoring as a Service: Ein modulares System für die Microservice-Architektur

Wir verfügen über ein Repository mit Metriken: Dies sind Graphite, die auf schnellen SSD-Laufwerken basieren, das sind bestimmte Aggregatoren für Metriken. Weiter – Grafana zur Anzeige von Dashboards und Moira als Alarm. Außerdem wollten wir ein System zum Auffinden von Anomalien entwickeln.

Standard: Überwachung 2.0

So sahen die Pläne im Jahr 2015 aus. Wir mussten aber nicht nur die Infrastruktur und den Service selbst vorbereiten, sondern auch die Dokumentation dafür. Wir haben für uns einen Unternehmensstandard entwickelt, den wir Monitoring 2.0 nennen. Welche Anforderungen wurden an das System gestellt?

  • ständige Verfügbarkeit;
  • metrisches Speicherintervall = 10 Sekunden;
  • strukturierte Speicherung von Metriken und Dashboards;
  • SLA > 99,99 %
  • Sammlung von Ereignismetriken über UDP (!).

Wir brauchten UDP, weil wir viel Verkehr und Ereignisse haben, die Metriken generieren. Wenn sie alle auf einmal in Graphit geschrieben werden, bricht das Repository zusammen. Außerdem haben wir für alle Metriken Präfixe der ersten Ebene gewählt.

Monitoring as a Service: Ein modulares System für die Microservice-Architektur

Jedes der Präfixe hat eine Eigenschaft. Es gibt Metriken für Server, Netzwerke, Container, Ressourcen, Anwendungen usw. Es wurde eine klare, strenge, typisierte Filterung implementiert, bei der wir die Metriken der ersten Ebene akzeptieren und den Rest einfach weglassen. So haben wir dieses System im Jahr 2015 geplant. Was ist in der Gegenwart?

Gegenwart: das Schema der Interaktion von Überwachungskomponenten

Zunächst überwachen wir Anwendungen: unseren PHP-Code, Anwendungen und Microservices – kurz gesagt alles, was unsere Entwickler schreiben. Alle Anwendungen senden Metriken über UDP an den Brubeck-Aggregator (statsd, neu geschrieben in C). Den Ergebnissen synthetischer Tests zufolge erwies es sich als das schnellste. Und es sendet die bereits aggregierten Metriken über TCP an Graphite.

Es verfügt über Metriken wie Timer. Das ist eine sehr praktische Sache. Beispielsweise senden Sie für jede Benutzerverbindung zum Dienst eine Antwortzeitmetrik an Brubeck. Es kamen eine Million Antworten, und der Aggregator gab nur 10 Messwerte aus. Sie haben die Anzahl der Personen, die gekommen sind, die maximale, minimale und durchschnittliche Antwortzeit, den Median und 4 Perzentile. Dann werden die Daten an Graphite übertragen und wir sehen sie alle live.

Wir haben auch eine Aggregation für Hardware, Software, Systemmetriken und unser altes Munin-Überwachungssystem (es funktionierte bei uns bis 2015). All dies sammeln wir über den C'ish-Daemon CollectD (in ihn ist eine ganze Reihe verschiedener Plug-Ins eingenäht, er kann alle Ressourcen des Hostsystems abfragen, auf dem er installiert ist, geben Sie einfach in der Konfiguration an, wo Daten geschrieben werden sollen ) und schreiben Sie Daten darüber in Graphite. Es unterstützt auch Python-Plugins und Shell-Skripte, sodass Sie Ihre eigenen benutzerdefinierten Lösungen schreiben können: CollectD sammelt diese Daten von einem lokalen oder Remote-Host (vorausgesetzt, Curl ist verfügbar) und sendet sie an Graphite.

Darüber hinaus werden alle von uns erfassten Metriken an Carbon-c-relay gesendet. Dies ist die Carbon Relay-Lösung von Graphite, modifiziert in C. Dabei handelt es sich um einen Router, der alle Metriken sammelt, die wir von unseren Aggregatoren senden, und sie über die Knoten weiterleitet. Außerdem prüft es in der Routing-Phase die Gültigkeit der Metriken. Erstens müssen sie mit dem Präfixschema übereinstimmen, das ich zuvor gezeigt habe, und zweitens müssen sie für Graphit gültig sein. Andernfalls fallen sie ab.

Anschließend sendet Carbon-c-relay die Metriken an den Graphite-Cluster. Wir verwenden den in Go neu geschriebenen Carbon-Cache als Hauptspeicher für Metriken. Go-Carbon ist aufgrund seines Multithreadings Carbon-Cache in der Leistung weit überlegen. Es nimmt Daten in sich auf und schreibt sie mithilfe des Whisper-Pakets (Standard, in Python geschrieben) auf die Festplatte. Um Daten aus unseren Speichern auszulesen, nutzen wir die Graphite API. Es arbeitet viel schneller als das Standard-Graphit-WEB. Was passiert als nächstes mit den Daten?

Sie gehen nach Grafana. Wir verwenden unsere Graphit-Cluster als Hauptdatenquelle und verfügen außerdem über Grafana als Webschnittstelle zum Anzeigen von Metriken und zum Erstellen von Dashboards. Für jeden ihrer Dienste erstellen Entwickler ihr eigenes Dashboard. Anschließend erstellen sie darauf basierende Diagramme, die die Metriken anzeigen, die sie aus ihren Anwendungen schreiben. Neben Grafana haben wir auch SLAM. Dies ist ein Python-Dämon, der SLA basierend auf Daten aus Graphit berechnet. Wie gesagt, wir haben mehrere Dutzend Microservices, von denen jeder seine eigenen Anforderungen hat. Mit Hilfe von SLAM gehen wir in die Dokumentation und vergleichen sie mit dem, was in Graphite enthalten ist, und vergleichen, wie die Anforderungen mit der Verfügbarkeit unserer Dienste übereinstimmen.

Noch weiter gehen: Alarmierung. Es ist mit einem starken System organisiert – Moira. Sie ist unabhängig, weil sie ihren eigenen Graphite unter der Haube hat. Entwickelt von den Jungs von SKB Kontur, geschrieben in Python und Go, vollständig Open Source. Moira erhält den gleichen Fluss, der auch in Graphite fließt. Wenn Ihr Speicher aus irgendeinem Grund ausfällt, funktioniert Ihre Benachrichtigung.

Wir haben Moira in Kubernetes bereitgestellt. Es verwendet einen Cluster von Redis-Servern als Hauptdatenbank. Das Ergebnis ist ein fehlertolerantes System. Es vergleicht den Metrikfluss mit der Liste der Auslöser: Wenn darin keine Erwähnungen enthalten sind, wird die Metrik verworfen. So ist sie in der Lage, Gigabytes an Messwerten pro Minute zu verarbeiten.

Wir haben außerdem ein Unternehmens-LDAP hinzugefügt, mit dessen Hilfe jeder Benutzer des Unternehmenssystems für sich selbst Benachrichtigungen zu vorhandenen (oder neu erstellten) Auslösern erstellen kann. Da Moira Graphit enthält, unterstützt es alle seine Funktionen. Man nimmt also zunächst die Zeile und kopiert sie in Grafana. Sehen Sie, wie die Daten in den Diagrammen angezeigt werden. Und dann nimmst du dieselbe Zeile und kopierst sie in Moira. Hängen Sie es mit Grenzen ein und erhalten Sie am Ausgang eine Warnung. Für all dies benötigen Sie keine besonderen Kenntnisse. Moira kann per SMS, E-Mail, Jira, Slack usw. benachrichtigen. Es unterstützt auch benutzerdefinierte Skripte. Wenn sie einen Auslöser hat und ein benutzerdefiniertes Skript oder eine Binärdatei abonniert hat, startet sie es und sendet diese JSON-Binärdatei an stdin. Dementsprechend sollte Ihr Programm es analysieren. Was Sie mit diesem JSON machen, bleibt Ihnen überlassen. Wenn Sie möchten, senden Sie es an Telegram, wenn Sie möchten, öffnen Sie Aufgaben in Jira und machen Sie, was Sie wollen.

Für die Alarmierung nutzen wir auch unsere eigene Entwicklung – Imagotag. Wir haben das Panel, das üblicherweise für elektronische Preisschilder in Geschäften verwendet wird, an unsere Bedürfnisse angepasst. Wir haben Auslöser von Moira mitgebracht. Es zeigt an, in welchem ​​Zustand sie sich befinden und wann sie passiert sind. Einige der Leute aus der Entwicklung haben Benachrichtigungen in Slack und in der E-Mail zugunsten dieses Panels aufgegeben.

Monitoring as a Service: Ein modulares System für die Microservice-Architektur

Da wir ein fortschrittliches Unternehmen sind, haben wir auch Kubernetes in diesem System überwacht. Es wird mithilfe von Heapster, das wir im Cluster installiert haben, in das System eingebunden, es sammelt Daten und sendet sie an Graphite. Im Ergebnis sieht das Schema so aus:

Monitoring as a Service: Ein modulares System für die Microservice-Architektur

Überwachungskomponenten

Hier ist eine Liste mit Links zu den Komponenten, die wir für diese Aufgabe verwendet haben. Alle davon sind Open Source.

Graphit:

Carbon-C-Relais:

github.com/grobian/carbon-c-relay

Brubeck:

github.com/github/brubeck

Gesammelt:

Collectd.org

Moira:

github.com/moira-alert

Grafana:

grafana.com

Heapster:

github.com/kubernetes/heapster

Statistik

Und hier sind einige Zahlen darüber, wie das System bei uns funktioniert.

Aggregator (brubeck)

Anzahl der Messwerte: ~ 300/Sek
Graphite Metrics Sendeintervall: 30 Sek
Serverressourcenauslastung: ~ 6 % CPU (wir sprechen von vollwertigen Servern); ~ 1 GB RAM; ~ 3 Mbit/s LAN

Graphit (Go-Carbon)

Anzahl der Metriken: ~ 1 / Min
Metrikaktualisierungsintervall: 30 Sek
Speicherschema für Metriken: 30 Sek. 35 Tage, 5 Min. 90 Tage, 10 Min. 365 Tage (vermittelt ein Verständnis dafür, was mit dem Dienst über einen langen Zeitraum passiert)
Serverressourcennutzung: ~10 % CPU; ~ 20 GB RAM; ~ 30 Mbit/s LAN

Flexibilität

Wir bei Avito schätzen die Flexibilität unseres Überwachungsdienstes sehr. Warum ist er eigentlich so geworden? Erstens sind seine Bestandteile austauschbar: sowohl die Komponenten selbst als auch ihre Versionen. Zweitens: Wartbarkeit. Da das gesamte Projekt auf Open Source basiert, können Sie den Code selbst bearbeiten, Änderungen vornehmen und Funktionen implementieren, die nicht standardmäßig verfügbar sind. Es werden recht gängige Stacks verwendet, hauptsächlich Go und Python, daher ist dies ganz einfach.

Hier ist ein Beispiel für ein echtes Problem. Eine Metrik in Graphite ist eine Datei. Es hat einen Namen. Dateiname = Metrikname. Und es gibt einen Weg dorthin. Dateinamen sind unter Linux auf 255 Zeichen beschränkt. Und wir haben (als „interne Kunden“) Leute aus der Datenbankabteilung. Sie sagen uns: „Wir wollen unsere SQL-Abfragen überwachen. Und sie sind nicht 255 Zeichen lang, sondern jeweils 8 MB. Wir möchten sie in Grafana anzeigen, die Parameter für diese Anfrage sehen und noch besser, wir wollen die Spitze solcher Anfragen sehen. Es wird großartig sein, wenn es in Echtzeit angezeigt wird. Und es wäre wirklich cool, sie in Alarmbereitschaft zu versetzen.“

Monitoring as a Service: Ein modulares System für die Microservice-Architektur
Als Beispiel dient das SQL-Abfragebeispiel aus Website postgrespro.ru

Wir erhöhen den Redis-Server und unsere Collectd-Plugins, die zu Postgres gehen, nehmen alle Daten von dort und senden Metriken an Graphite. Aber wir ersetzen den Namen der Metrik durch Hashes. Derselbe Hash wird gleichzeitig als Schlüssel und die gesamte SQL-Abfrage als Wert an Redis gesendet. Es bleibt uns überlassen, Grafana in die Lage zu versetzen, zu Redis zu gehen und diese Informationen zu übernehmen. Wir öffnen die Graphite-API, weil Dies ist die Hauptschnittstelle für die Interaktion aller Überwachungskomponenten mit Graphit, und wir geben dort eine neue Funktion namens aliasByHash() ein – wir erhalten den Namen der Metrik von Grafana und verwenden ihn in einer Anfrage an Redis als Schlüssel Als Antwort erhalten wir den Wert des Schlüssels, der unsere „SQL-Abfrage“ ist. Daher haben wir die Anzeige einer SQL-Abfrage, die dort theoretisch nicht angezeigt werden konnte, zusammen mit Statistiken dazu (Aufrufe, Zeilen, total_time, ...) nach Grafana gebracht.

Ergebnisse

Verfügbarkeit. Unser Überwachungsservice ist rund um die Uhr für jede Anwendung und jeden Code verfügbar. Wenn Sie Zugriff auf die Speicher haben, können Sie Daten in den Dienst schreiben. Sprache ist nicht wichtig, Entscheidungen sind nicht wichtig. Sie müssen nur wissen, wie man einen Socket öffnet, dort eine Metrik wirft und den Socket schließt.

Zuverlässigkeit. Alle Komponenten sind fehlertolerant und bewältigen unsere Arbeitslasten gut.

Niedrige Einstiegsschwelle. Um dieses System nutzen zu können, müssen Sie keine Programmiersprachen und Abfragen in Grafana erlernen. Öffnen Sie einfach Ihre Anwendung, fügen Sie einen Socket hinzu, der Metriken an Graphite sendet, schließen Sie sie, öffnen Sie Grafana, erstellen Sie dort Dashboards, sehen Sie sich das Verhalten Ihrer Metriken an und erhalten Sie Benachrichtigungen über Moira.

Unabhängigkeit. Sie können dies alles selbst tun, ohne die Hilfe von DevOps-Ingenieuren. Und das ist eine Überfunktion, denn Sie können Ihr Projekt jetzt überwachen und müssen niemanden bitten – weder um mit der Arbeit zu beginnen, noch um Änderungen vorzunehmen.

Was streben wir an?

Alles, was unten aufgeführt ist, sind nicht nur abstrakte Gedanken, sondern etwas, zu dem zumindest die ersten Schritte unternommen wurden.

  1. Anomaliedetektor. Wir möchten einen Dienst erstellen, der auf unsere Graphite-Speicher zugreift und jede Metrik mithilfe verschiedener Algorithmen überprüft. Es gibt bereits Algorithmen, die wir sehen wollen, es gibt Daten, wir wissen, wie man damit arbeitet.
  2. Metadaten. Wir haben viele Dienste, sie ändern sich im Laufe der Zeit, ebenso wie die Menschen, die mit ihnen arbeiten. Das manuelle Führen von Aufzeichnungen ist keine Option. Daher sind Metadaten jetzt in unsere Microservices eingebettet. Darin wird angegeben, wer es entwickelt hat, mit welchen Sprachen es interagiert, SLA-Anforderungen und wo und an wen Benachrichtigungen gesendet werden sollen. Bei der Bereitstellung eines Dienstes werden alle Entitätsdaten unabhängig voneinander erstellt. Als Ergebnis erhalten Sie zwei Links – einen für Trigger, den anderen für Dashboards in Grafana.
  3. Überwachung in jedem Zuhause. Wir glauben, dass alle Entwickler ein solches System verwenden sollten. In diesem Fall verstehen Sie immer, wo sich Ihr Traffic befindet, was mit ihm passiert, wo er hinfällt, wo er Schwachstellen hat. Wenn beispielsweise etwas kommt und Ihren Dienst zum Absturz bringt, erfahren Sie dies nicht durch einen Anruf des Managers, sondern durch eine Benachrichtigung und können sofort neue Protokolle öffnen und sehen, was dort passiert ist.
  4. Hochleistung. Unser Projekt wächst stetig und verarbeitet heute etwa 2 metrische Werte pro Minute. Vor einem Jahr lag diese Zahl bei 000. Und das Wachstum geht weiter, und das bedeutet, dass Graphite (Whisper) nach einiger Zeit beginnt, das Festplatten-Subsystem sehr stark zu belasten. Wie gesagt, dieses Überwachungssystem ist aufgrund der Austauschbarkeit der Komponenten sehr vielseitig. Jemand, der speziell für Graphite zuständig ist, pflegt und erweitert seine Infrastruktur ständig, aber wir haben uns für den anderen Weg entschieden: die Nutzung Clickhouse als Aufbewahrungsort für unsere Kennzahlen. Dieser Übergang ist fast abgeschlossen, und ich werde Ihnen in Kürze ausführlicher erzählen, wie er durchgeführt wurde: Welche Schwierigkeiten gab es und wie wurden sie überwunden, wie der Migrationsprozess verlief, ich werde die als Bindung ausgewählten Komponenten und ihre Konfigurationen beschreiben.

Vielen Dank für Ihre Aufmerksamkeit! Stellen Sie Ihre Fragen zum Thema, ich werde versuchen, sie hier oder in den folgenden Beiträgen zu beantworten. Vielleicht hat jemand Erfahrung mit dem Aufbau eines ähnlichen Überwachungssystems oder dem Wechsel zu Clickhouse in einer ähnlichen Situation – teilen Sie es in den Kommentaren.

Source: habr.com

Kommentar hinzufügen