Monitoring as a service: ett modulärt system för mikrotjänstarkitektur

Idag, förutom monolitisk kod, inkluderar vårt projekt dussintals mikrotjänster. Var och en av dem måste övervakas. Att göra detta i en sådan skala med hjälp av DevOps-ingenjörer är problematiskt. Vi har utvecklat ett övervakningssystem som fungerar som en tjänst för utvecklare. De kan självständigt skriva mätvärden i övervakningssystemet, använda dem, bygga instrumentpaneler baserade på dem och bifoga varningar till dem som kommer att utlösas när tröskelvärden nås. För DevOps-ingenjörer, endast infrastruktur och dokumentation.

Det här inlägget är en utskrift av mitt tal med vår avsnitt på RIT++. Många bad oss ​​göra textversioner av rapporter därifrån. Om du var på konferensen eller tittade på videon kommer du inte att hitta något nytt. Och alla andra - välkomna till katten. Jag ska berätta hur vi kom till ett sådant system, hur det fungerar och hur vi planerar att uppdatera det.

Monitoring as a service: ett modulärt system för mikrotjänstarkitektur

Det förflutna: planer och planer

Hur kom vi fram till det nuvarande övervakningssystemet? För att svara på denna fråga måste du gå till 2015. Så här såg det ut då:

Monitoring as a service: ett modulärt system för mikrotjänstarkitektur

Vi hade cirka 24 noder som ansvarade för övervakningen. Det finns ett helt paket med olika kronor, skript, demoner som på något sätt övervakar något, skickar meddelanden och utför funktioner. Vi trodde att ju längre vi gick, desto mindre lönsamt skulle ett sådant system vara. Det är ingen idé att utveckla det: det är för krångligt.
Vi beslutade att välja de övervakningselement som vi kommer att behålla och utveckla, och de som vi kommer att överge. Det fanns 19. Bara grafiter, aggregatorer och Grafana som instrumentpanel återstod. Men hur kommer det nya systemet att se ut? Så här:

Monitoring as a service: ett modulärt system för mikrotjänstarkitektur

Vi har en metriklagring: det här är grafiter, som kommer att baseras på snabba SSD-enheter, dessa är vissa aggregatorer för mätvärden. Nästa - Grafana för att visa instrumentpaneler och Moira för att varna. Vi ville också utveckla ett system för att söka efter anomalier.

Standard: Monitoring 2.0

Så här såg planerna ut 2015. Men vi var tvungna att förbereda inte bara infrastrukturen och själva tjänsten utan även dokumentationen för det. Vi har tagit fram en företagsstandard för oss själva, som vi kallar monitoring 2.0. Vilka krav ställdes på systemet?

  • konstant tillgänglighet;
  • lagringsintervall för mätvärden = 10 sekunder;
  • strukturerad lagring av mätvärden och instrumentpaneler;
  • SLA > 99,99 %
  • insamling av händelsemått via UDP (!).

Vi behövde UDP eftersom vi har ett stort flöde av trafik och händelser som genererar mätvärden. Om du skriver in dem alla i grafit på en gång kommer lagringen att kollapsa. Vi valde också prefix på första nivån för alla mätvärden.

Monitoring as a service: ett modulärt system för mikrotjänstarkitektur

Vart och ett av prefixen har en viss egenskap. Det finns mätvärden för servrar, nätverk, behållare, resurser, applikationer och så vidare. Tydlig, strikt, typad filtrering har implementerats, där vi accepterar mätvärden på första nivån och helt enkelt släpper resten. Så här planerade vi detta system 2015. Vad finns i nuet?

Närvarande: diagram över interaktion mellan övervakningskomponenter

Först och främst övervakar vi applikationer: vår PHP-kod, applikationer och mikrotjänster – kort sagt allt som våra utvecklare skriver. Alla applikationer skickar mätvärden via UDP till Brubeck-aggregatorn (statsd, omskriven i C). Det visade sig vara snabbast i syntetiska tester. Och den skickar redan aggregerade mätvärden till Graphite via TCP.

Den har en typ av mätvärden som kallas timers. Detta är en mycket bekväm sak. Till exempel, för varje användaranslutning till tjänsten skickar du ett mått med svarstid till Brubeck. En miljon svar kom in, men aggregatorn returnerade bara 10 mätvärden. Du har antalet personer som kom, maximal, lägsta och genomsnittlig svarstid, median och 4 percentiler. Sedan överförs data till Graphite och vi ser det hela live.

Vi har även aggregering för mått på hårdvara, mjukvara, systemmått och vårt gamla Munin-övervakningssystem (det fungerade för oss fram till 2015). Vi samlar in allt detta genom C-demonen CollectD (den har en hel massa olika plugins inbyggda i den, den kan polla alla resurserna i värdsystemet som den är installerad på, ange bara i konfigurationen var data ska skrivas) och skriv data till Graphite genom den. Den stöder också python-plugins och skalskript, så att du kan skriva dina egna anpassade lösningar: CollectD kommer att samla in denna data från en lokal eller fjärrvärd (förutsatt att Curl) skickas till Graphite.

Sedan skickar vi alla mätvärden som vi samlat in till Carbon-c-relay. Det här är Carbon Relay-lösningen från Graphite, modifierad i C. Detta är en router som samlar in alla mätvärden som vi skickar från våra aggregatorer och dirigerar dem till noder. Också i routingstadiet kontrollerar den mätvärdenas giltighet. För det första måste de motsvara prefixschemat som jag visade tidigare och för det andra är de giltiga för grafit. Annars kommer de att falla.

Carbon-c-relä skickar sedan måtten till grafitklustret. Vi använder Carbon-cache, omskriven i Go, som den huvudsakliga lagringen av mätvärden. Go-carbon överträffar Carbon-cache, tack vare sin multithreading. Den tar emot data och skriver den till diskar med hjälp av whisper-paketet (standard, skrivet i python). För att läsa data från våra lagringar använder vi Graphite API. Det är mycket snabbare än standard Graphite WEB. Vad händer med datan härnäst?

De går till Grafana. Vi använder våra grafitkluster som den huvudsakliga datakällan, plus att vi har Grafana som ett webbgränssnitt för att visa mätvärden och bygga instrumentpaneler. För var och en av deras tjänster skapar utvecklare sin egen instrumentpanel. Sedan bygger de grafer utifrån dem, som visar de mätvärden de skriver från sina applikationer. Förutom Grafana har vi även SLAM. Detta är en pytondemon som beräknar SLA baserat på data från grafit. Som jag redan sa har vi flera dussin mikrotjänster, som var och en har sina egna krav. Med hjälp av SLAM går vi till dokumentationen och jämför med det som finns i Graphite och jämför hur väl kraven matchar tillgängligheten på våra tjänster.

Låt oss gå längre: larma. Det är organiserat med hjälp av ett starkt system - Moira. Den är oberoende eftersom den har sin egen grafit under huven. Utvecklad av killarna från SKB "Kontur", skriven i python och Go, helt öppen källkod. Moira får samma flöde som går in i grafiter. Om din lagring av någon anledning dör kommer din varning fortfarande att fungera.

Vi distribuerade Moira i Kubernetes; den använder ett kluster av Redis-servrar som huvuddatabas. Resultatet blev ett feltåligt system. Den jämför strömmen av mätvärden med listan över utlösare: om det inte finns några omnämnanden i den, tappar den mätvärdet. Så det kan smälta gigabyte av mätvärden per minut.

Vi bifogade även en företags-LDAP till den, med hjälp av vilken varje användare av företagssystemet kan skapa aviseringar för sig själva baserat på befintliga (eller nyskapade) triggers. Eftersom Moira innehåller grafit stöder den alla dess funktioner. Så du tar först linjen och kopierar den till Grafana. Se hur data visas på graferna. Och sedan tar du samma linje och kopierar den till Moira. Du hänger den med limits och får en varning vid utgången. För att göra allt detta behöver du ingen specifik kunskap. Moira kan larma via SMS, e-post, Jira, Slack... Det stöder även exekvering av anpassade skript. När en trigger händer med henne och hon prenumererar på ett anpassat skript eller binär, kör hon det och skickar JSON till denna binär på stdin. Följaktligen måste ditt program analysera det. Vad du kommer att göra med denna JSON är upp till dig. Om du vill, skicka det till Telegram, om du vill, öppna uppgifter i Jira, gör vad som helst.

Vi använder även vår egen utveckling för att larma – Imagotag. Vi anpassade panelen, som vanligtvis används för elektroniska prislappar i butik, för att passa våra behov. Vi tog triggers från Moira till det. Den indikerar vilket tillstånd de är i och när de inträffade. Några av utvecklingskillarna övergav meddelanden i Slack och e-post till förmån för den här panelen.

Monitoring as a service: ett modulärt system för mikrotjänstarkitektur

Tja, eftersom vi är ett progressivt företag övervakade vi även Kubernetes i det här systemet. Vi inkluderade det i systemet med hjälp av Heapster, som vi installerade i klustret, det samlar in data och skickar det till Graphite. Som ett resultat ser diagrammet ut så här:

Monitoring as a service: ett modulärt system för mikrotjänstarkitektur

Övervakning av komponenter

Här är en lista med länkar till komponenterna vi använde för denna uppgift. Alla är öppen källkod.

Grafit:

Kol-c-relä:

github.com/grobian/carbon-c-relay

Brubeck:

github.com/github/brubeck

Samlade:

collectd.org

Moira:

github.com/moira-alert

Grafana:

grafana.com

Heapster:

github.com/kubernetes/heapster

Statistik

Och här är några siffror om hur systemet fungerar för oss.

Aggregator (brubeck)

Antal mätvärden: ~300 000/sek
Intervall för att skicka mätvärden till Graphite: 30 sek
Serverresursanvändning: ~ 6% CPU (vi talar om fullfjädrade servrar); ~ 1 Gb RAM; ~3 Mbps LAN

Grafit (go-carbon)

Antal mätvärden: ~ 1 600 000 / min
Uppdateringsintervall för statistik: 30 sek
Måttlagringsschema: 30 sek 35d, 5min 90d, 10min 365d (ger dig en förståelse för vad som händer med tjänsten under en lång tidsperiod)
Serverresursanvändning: ~10% CPU; ~ 20 Gb RAM; ~30 Mbps LAN

flexibilitet

Vi på Avito värdesätter verkligen flexibilitet i vår övervakningstjänst. Varför blev han så här egentligen? För det första är dess komponenter utbytbara: både själva komponenterna och deras versioner. För det andra, stödbarhet. Eftersom hela projektet är öppen källkod kan du själv redigera koden, göra ändringar och implementera funktioner som inte är tillgängliga direkt. Ganska vanliga stackar används, främst Go och Python, så detta görs helt enkelt.

Här är ett exempel på ett verkligt problem. Ett mått i Graphite är en fil. Den har ett namn. Filnamn = metriskt namn. Och det finns ett sätt att ta sig dit. Filnamn i Linux är begränsade till 255 tecken. Och vi har (som "interna kunder") killar från databasavdelningen. De säger till oss: "Vi vill övervaka våra SQL-frågor. Och de är inte 255 tecken, utan 8 MB vardera. Vi vill visa dem i Grafana, se parametrarna för denna begäran, och ännu bättre, vi vill se toppen av sådana förfrågningar. Det kommer att vara bra om det visas i realtid. Det skulle vara riktigt coolt att sätta dem i larmet.”

Monitoring as a service: ett modulärt system för mikrotjänstarkitektur
Exempel SQL-frågan är hämtad som ett exempel från webbplats postgrespro.ru

Vi sätter upp en Redis-server och använder våra Collectd-plugins, som går till Postgres och tar all data därifrån och skickar mätvärden till Graphite. Men vi ersätter det metriska namnet med hash. Vi skickar samtidigt samma hash till Redis som en nyckel, och hela SQL-frågan som ett värde. Allt vi behöver göra är att se till att Grafana kan åka till Redis och ta denna information. Vi öppnar Graphite API eftersom... detta är huvudgränssnittet för interaktionen av alla övervakningskomponenter med grafit, och vi anger en ny funktion där som heter aliasByHash() - från Grafana får vi namnet på måtten och använder den i en begäran till Redis som en nyckel, i svar får vi värdet av nyckeln, vilket är vår "SQL-fråga" " Således visade vi i Grafana en visning av en SQL-fråga, som i teorin var omöjlig att visa där, tillsammans med statistik på den (samtal, rader, total_tid, ...).

Resultat av

Tillgänglighet. Vår övervakningstjänst är tillgänglig 24/7 från vilken applikation och vilken kod som helst. Om du har tillgång till lagringsmöjligheter kan du skriva data till tjänsten. Språket är inte viktigt, besluten är inte viktiga. Du behöver bara veta hur man öppnar ett uttag, sätter ett mått där och stänger uttaget.

Tillförlitlighet. Alla komponenter är feltoleranta och klarar vår last väl.

Låg inträdesbarriär. För att använda detta system behöver du inte lära dig programmeringsspråk och frågor i Grafana. Öppna bara din applikation, skriv in en socket i den som skickar mätvärden till Graphite, stäng den, öppna Grafana, skapa instrumentpaneler där och titta på beteendet hos dina mätvärden, ta emot aviseringar via Moira.

Oberoende. Du kan göra allt detta själv, utan hjälp av DevOps-ingenjörer. Och detta är en fördel, eftersom du kan övervaka ditt projekt just nu, du behöver inte fråga någon - varken för att börja arbeta eller göra ändringar.

Vad strävar vi efter?

Allt som listas nedan är inte bara abstrakta tankar, utan något som åtminstone de första stegen har tagits mot.

  1. Anomalidetektor. Vi vill skapa en tjänst som går till våra Graphite-lagringar och kontrollerar varje mätvärde med hjälp av olika algoritmer. Det finns redan algoritmer som vi vill se, det finns data, vi vet hur man arbetar med det.
  2. Metadata. Vi har många tjänster, de förändras över tid, precis som de som arbetar med dem. Att ständigt underhålla dokumentationen manuellt är inte ett alternativ. Det är därför vi nu bäddar in metadata i våra mikrotjänster. Den anger vem som har utvecklat den, vilka språk den interagerar med, SLA-krav, var och till vem aviseringar ska skickas. När en tjänst distribueras skapas all enhetsdata oberoende. Som ett resultat får du två länkar - en till triggers, den andra till instrumentpaneler i Grafana.
  3. Övervakning i varje hem. Vi anser att alla utvecklare bör använda ett sådant system. I det här fallet förstår du alltid var din trafik är, vad som händer med den, var den faller, var dess svagheter finns. Om till exempel något kommer och kraschar din tjänst, kommer du att lära dig om det inte under ett samtal från chefen, utan från en varning, och du kan omedelbart öppna de senaste loggarna och se vad som hände där.
  4. Hög prestanda. Vårt projekt växer ständigt och idag bearbetar det cirka 2 000 000 metriska värden per minut. För ett år sedan var denna siffra 500 000. Och tillväxten fortsätter, och det betyder att efter en tid kommer Graphite (whisper) att börja belasta diskundersystemet hårt. Som jag redan har sagt är detta övervakningssystem ganska universellt på grund av utbytbarheten av komponenter. Någon underhåller och utökar ständigt sin infrastruktur specifikt för Graphite, men vi bestämde oss för att gå en annan väg: använd klickhus som ett arkiv för våra mätvärden. Denna övergång är nästan klar, och mycket snart kommer jag att berätta mer i detalj hur detta gjordes: vilka svårigheter som fanns och hur de övervanns, hur migreringsprocessen gick, jag kommer att beskriva de komponenter som valts som bindande och deras konfigurationer.

Tack för din uppmärksamhet! Ställ dina frågor om ämnet, jag ska försöka svara här eller i följande inlägg. Kanske har någon erfarenhet av att bygga ett liknande övervakningssystem eller byta till Clickhouse i en liknande situation - dela det i kommentarerna.

Källa: will.com

Lägg en kommentar