Monitoraggio come servizio: sistema modulare per architetture a microservizi

Oggi nel nostro progetto, oltre al codice monolitico, funzionano dozzine di microservizi. Ognuno di essi richiede monitoraggio. Farlo con le sole forze degli ingegneri DevOps è problematico. Abbiamo sviluppato un sistema di monitoraggio che funziona come servizio per gli sviluppatori. Possono scrivere metriche nel sistema di monitoraggio, utilizzarle, costruire dashboard e collegare avvisi che si attivano al raggiungimento di valori soglia. Gli ingegneri DevOps si occupano solo dell'infrastruttura e della documentazione.

Questo post è la trascrizione del mio intervento durante la nostra sessione a RIT++. Molti ci hanno chiesto di realizzare versioni testuali delle presentazioni. Se hai partecipato alla conferenza o hai visto il video, non troverai nulla di nuovo. A tutti gli altri, benvenuti sotto il cat. Racconterò come siamo arrivati a questo sistema, come funziona e come prevediamo di aggiornarlo.

Monitoraggio come servizio: sistema modulare per architetture a microservizi

Passato: schemi e piani

Come siamo arrivati al sistema di monitoraggio attuale? Per rispondere a questa domanda, dobbiamo tornare al 2015. Ecco com'era allora:

Monitoraggio come servizio: sistema modulare per architetture a microservizi

Avevamo circa 24 nodi dedicati al monitoraggio. Qui ci sono vari cron, script e demoni che monitorano qualcosa in qualche modo, inviano messaggi e svolgono funzioni. Abbiamo pensato che più si andava avanti, meno questa sistema sarebbe stata sostenibile. Non ha senso svilupparla ulteriormente: troppo ingombrante.
Abbiamo deciso quali elementi di monitoraggio mantenere e sviluppare e quali abbandonare. Ne sono risultati 19. Sono rimasti solo i Graphite, gli aggregatori e Grafana come dashboard. Ma come apparirà il nuovo sistema? Ecco come:

Monitoraggio come servizio: sistema modulare per architetture a microservizi

Abbiamo un repository di metriche: sono i Graphite che si baseranno su veloci dischi SSD, insieme a specifici aggregatori per le metriche. Poi, Grafana per visualizzare le dashboard e Moira come sistema di allerta. Volevamo anche sviluppare un sistema per la rilevazione delle anomalie.

Standard: Monitoraggio 2.0

Questi erano i piani nel 2015. Ma dovevamo preparare non solo l'infrastruttura e il servizio stesso, ma anche la documentazione per esso. Abbiamo sviluppato un standard aziendale che abbiamo chiamato monitoraggio 2.0. Quali erano i requisiti per il sistema?

  • disponibilità continua;
  • intervallo di conservazione delle metriche = 10 secondi;
  • archiviazione strutturata delle metriche e dei dashboard;
  • SLA > 99,99%
  • raccolta di metriche eventi tramite UDP (!).

Abbiamo bisogno di UDP poiché abbiamo un elevato flusso di traffico e eventi che generano metriche. Se scrivessimo tutte le metriche direttamente su Graphite, il sistema si rallenterebbe. Abbiamo anche scelto i prefissi di primo livello per tutte le metriche.

Monitoraggio come servizio: sistema modulare per architetture a microservizi

Ogni prefisso rappresenta una specifica proprietà. Ci sono metriche per server, reti, container, risorse, applicazioni e così via. È implementata una filtrazione chiara, rigorosa e tipizzata, dove accettiamo solo le metriche di primo livello e scartiamo le altre. È così che abbiamo pianificato questo sistema nel 2015. E come siamo messi adesso?

Presente: schema di interazione dei componenti di monitoraggio

In primo luogo monitoriamo le applicazioni: il nostro codice PHP, le applicazioni e i microservizi — in breve, tutto ciò che sviluppano i nostri programmatori. Tutte le applicazioni inviano metriche all'aggregatore Brubeck (statsd, riscritto in C) tramite UDP. Si è rivelato il più veloce nei test sintetici. E invia già le metriche aggregate a Graphite tramite TCP.

Questo tipo di metriche include i timer. È uno strumento molto utile. Ad esempio, per ogni connessione utente al servizio, inviate a Brubeck una metrica con il tempo di risposta. Se ricevete un milione di risposte, l'aggregatore emette solo 10 metriche. Avete il numero di visitatori, il tempo di risposta massimo, minimo, medio, la mediana e 4 percentile. Poi i dati vengono trasferiti in Graphite e possiamo vederli tutti in tempo reale.

Abbiamo anche l'aggregazione delle metriche hardware, software, delle metriche di sistema e del nostro vecchio sistema di monitoraggio Munin (utilizzato fino al 2015). Tutto questo lo raccogliamo tramite il demone CollectD (che include un intero pacchetto di vari plugin, che permette di interrogare tutte le risorse del sistema host su cui è installato; basta specificare nella configurazione dove inviare i dati) e scriviamo i dati in Graphite attraverso di esso. Supporta anche plugin python e script shell, quindi potete creare le vostre soluzioni personalizzate: CollectD raccoglierà questi dati da un host locale o remoto (ad esempio, utilizzando Curl) e li invierà a Graphite.

Successivamente, tutte le metriche che abbiamo raccolto vengono inviate a Carbon-c-relay. Questa è la soluzione Carbon Relay di Graphite, adattata in C. Si tratta di un router che raccoglie tutte le metriche inviate dai nostri aggregatori e le instrada verso i nodi. Durante la fase di instradamento, verifica anche la validità delle metriche. Devono, innanzitutto, corrispondere allo schema con i prefissi che ho mostrato in precedenza e, in secondo luogo, essere valide per Graphite. In caso contrario, vengono scartate.

Successivamente, Carbon-c-relay invia le metriche al cluster di Graphite. Usiamo Carbon-cache come archivio principale per le metriche, riscritto in Go. Go-carbon, a causa della sua multithread, supera di gran lunga in prestazioni Carbon-cache. Accetta i dati e li scrive su disco utilizzando il pacchetto whisper (standard, scritto in Python). Per leggere i dati dai nostri archivi, utilizziamo l'API di Graphite. Questa è molto più veloce rispetto al Graphite WEB standard. Cosa succede ai dati dopo?

I dati vengono visualizzati in Grafana. Utilizziamo i nostri cluster Graphite come principale fonte di dati, con Grafana come interfaccia web per visualizzare le metriche e costruire dashboard. Ogni sviluppatore crea una propria dashboard per ciascun servizio. Successivamente, costruiscono grafici che mostrano le metriche registrate dalle loro applicazioni. Oltre a Grafana, abbiamo anche SLAM, un demone Python che calcola il SLA in base ai dati di Graphite. Come ho già detto, possediamo diverse decine di microservizi, ognuno con requisiti specifici. Con SLAM, verifichiamo i requisiti nella documentazione confrontandoli con quanto presente in Graphite, analizzando quanto siano conformi alla disponibilità dei nostri servizi.

Passiamo ora all'alerting. È organizzato tramite un potente sistema: Moira. È indipendente perché utilizza un proprio Graphite. Sviluppato dai ragazzi di SKB "Kontur", scritto in Python e Go, è completamente open source. Moira riceve lo stesso flusso di dati che viene inviato a Graphite. Se per qualche motivo il tuo storage smette di funzionare, l'alerting continuerà a funzionare.

Moira è stata distribuita su Kubernetes, utilizzando un cluster di server Redis come database principale. Ne è risultata un sistema resiliente. Confronta il flusso delle metriche con un elenco di attivatori: se non ci sono menzioni, scarta la metrica. Così, è in grado di elaborare gigabyte di metriche al minuto.

Inoltre, abbiamo integrato un LDAP aziendale, grazie al quale ogni utente del sistema aziendale può creare notifiche per i trigger esistenti (o di nuova creazione). Poiché Moira include Graphite, supporta tutte le sue funzionalità. Quindi, per prima cosa, prendi una riga e copiala in Grafana. Controlla come i dati vengono visualizzati nei grafici. Poi prendi quella stessa riga e copiala in Moira. Imposta i limiti e ottieni gli avvisi in uscita. Per fare tutto ciò, non hai bisogno di alcuna conoscenza specifica. Moira può inviare avvisi tramite SMS, email, in Jira, Slack… Supporta anche l'esecuzione di script personalizzati. Quando si verifica un trigger e Moira è iscritta a uno script personalizzato o a un binario, lo esegue, passando il JSON a stdin di quel binario. Di conseguenza, il tuo programma deve analizzarlo. Cosa fare con questo JSON è una tua decisione. Vuoi inviarlo su Telegram, vuoi aprire task in Jira, fai ciò che preferisci.

Per il monitoraggio utilizziamo anche un nostro sviluppo chiamato Imagotag. Abbiamo adattato il pannello solitamente utilizzato per i prezzi elettronici nei negozi alle nostre esigenze. Abbiamo integrato i trigger di Moira, dove è indicato il loro stato e il momento in cui si sono verificati. Alcuni membri del team di sviluppo hanno rinunciato alle notifiche su Slack e via email in favore di questo pannello.

Monitoraggio come servizio: sistema modulare per architetture a microservizi

Essendo un'azienda progressista, abbiamo monitorato anche Kubernetes in questo sistema. Lo abbiamo integrato tramite Heapster, che abbiamo installato nel cluster; esso raccoglie i dati e li invia a Graphite. Alla fine, lo schema appare così:

Monitoraggio come servizio: sistema modulare per architetture a microservizi

Componenti di monitoraggio

Ecco un elenco dei link ai componenti che abbiamo utilizzato per questo compito. Sono tutti open source.

Graphite:

Carbon-c-relay:

github.com/grobian/carbon-c-relay

Brubeck:

github.com/github/brubeck

Collectd:

collectd.org

Moira:

github.com/moira-alert

Grafana:

grafana.com

Heapster:

github.com/kubernetes/heapster

Statistiche

Ecco alcuni dati su come il sistema funziona da noi.

Aggregator (brubeck)

Numero di metriche: ~ 300.000 / sec
Intervallo di invio delle metriche a Graphite: 30 sec
Utilizzo delle risorse del server: ~ 6% CPU (riferito a server completi); ~ 1Gb RAM; ~ 3 Mbps LAN

Graphite (go-carbon)

Numero di metriche: ~ 1.600.000 / min
Intervallo di aggiornamento delle metriche: 30 sec
Schema di archiviazione delle metriche: 30sec 35d, 5min 90d, 10min 365d (fornisce comprensione di cosa succede al servizio nel lungo periodo)
Utilizzo delle risorse del server: ~ 10% CPU; ~ 20Gb RAM; ~ 30 Mbps LAN

Flessibilità

In Avito, valorizziamo molto la flessibilità del nostro servizio di monitoraggio. Perché è, appunto, così? In primo luogo, le sue componenti sono intercambiabili: sia i componenti stessi che le loro versioni. In secondo luogo, la manutenibilità. Poiché l'intero progetto si basa su software open source, potete modificare il codice, apportare cambiamenti e implementare funzionalità non disponibili di default. Vengono utilizzati stack abbastanza comuni, principalmente Go e Python, quindi è relativamente semplice farlo.

Ecco un esempio di un problema reale. Una metrica in Graphite è un file. Ha un nome. Il nome del file è uguale al nome della metrica. E c'è un percorso per arrivarci. I nomi dei file in Linux sono limitati a 255 caratteri. Ma noi abbiamo (come "clienti interni") ragazzi del dipartimento database. Loro ci dicono: "Vogliamo monitorare le nostre query SQL. E queste non sono 255 caratteri, ma 8 MB ciascuna. Vogliamo visualizzarle in Grafana, vedere i parametri di questa query, e sarebbe ancora meglio vedere le query più frequenti. Sarebbe fantastico se potessero essere visualizzate in tempo reale. E sarebbe davvero straordinario poterle inserire negli allerta."

Monitoraggio come servizio: sistema modulare per architetture a microservizi
Esempio di query SQL preso come esempio da sito postgrespro.ru

Stiamo avviando il server Redis e utilizzando i nostri plugin Collectd, che accedono a Postgres per raccogliere tutti i dati e inviare le metriche a Graphite. Ma cambiamo il nome della metrica in hash. Questo stesso hash viene inviato a Redis come chiave, e l'intera query SQL come valore. Dobbiamo fare in modo che Grafana possa accedere a Redis e recuperare queste informazioni. Apriamo l'API di Graphite, poiché è l'interfaccia principale per l'interazione di tutti i componenti di monitoraggio con Graphite, e inseriamo una nuova funzione chiamata aliasByHash() — riceviamo il nome della metrica da Grafana e lo usiamo nella richiesta a Redis come chiave, ricevendo in risposta il valore della chiave, che è la nostra “query SQL”. In questo modo, abbiamo visualizzato in Grafana la query SQL, che inizialmente non poteva essere visualizzata, insieme alle statistiche (calls, rows, total_time, …).

Risultati

Accessibilità. Il nostro servizio di monitoraggio è disponibile 24 ore su 24, 7 giorni su 7 da qualsiasi applicazione e qualsiasi codice. Se hai accesso ai repository, puoi inviare dati al servizio. Il linguaggio non è importante, le soluzioni non contano. Devi solo sapere come aprire un socket, inviare una metrica e chiudere il socket.

Affidabilità. Tutti i componenti sono ridondanti e gestiscono bene i nostri carichi.

Basso rischio di ingresso. Per utilizzare questo sistema, non è necessario studiare linguaggi di programmazione e query in Grafana. Basta aprire la propria applicazione, inserire il socket che invierà le metriche a Graphite, chiuderla, aprire Grafana, creare i dashboard e osservare il comportamento delle metriche, ricevendo notifiche tramite Moira.

Autonomia. Tutto questo può essere fatto autonomamente, senza l'aiuto di ingegneri DevOps. È un sovraccarico, perché puoi monitorare il tuo progetto in questo momento, senza chiedere a nessuno - né per iniziare il lavoro, né per apportare modifiche.

A cosa aspiriamo?

Tutto ciò che segue non sono solo pensieri astratti, ma ciò a cui sono stati fatti almeno i primi passi.

  1. Rilevatore di anomalie. Vogliamo implementare un servizio che visiterà i nostri archivi Graphite e controllerà ogni metrica con vari algoritmi. Abbiamo già algoritmi che vogliamo esaminare, ci sono dati, sappiamo come lavorare con essi.
  2. Metadati. Abbiamo molti servizi che cambiano nel tempo, proprio come le persone che vi lavorano. Tenere la documentazione aggiornata manualmente non è un'opzione. Per questo motivo, ora i nostri microservizi integrano i metadati. Qui sono indicati chi lo ha sviluppato, i linguaggi con cui interagisce, i requisiti SLA e dove e a chi inviare le notifiche. Durante il deploy del servizio, tutti i dati delle entità vengono creati automaticamente. In questo modo, riceverete due link: uno per i trigger e l'altro per i dashboard in Grafana.
  3. Monitoraggio in ogni casa. Crediamo che un sistema simile dovrebbe essere utilizzato da tutti gli sviluppatori. In questo modo, avete sempre chiaro dove si trova il vostro traffico, cosa gli succede, dove cade e dove ha punti deboli. Se, ad esempio, qualcosa arriva e manda in crash il vostro servizio, lo scoprirete non durante una telefonata dal manager, ma da un avviso, e potrete subito aprire i log recenti e controllare cosa è successo.
  4. Elevata prestazione. Il nostro progetto è in continua crescita e oggi elabora circa 2.000.000 valori metrici al minuto. Un anno fa questo numero era di 500.000. La crescita continua, e ciò significa che, a un certo punto, Graphite (whisper) inizierà a sovraccaricare pesantemente il sistema di archiviazione. Come già accennato, questo sistema di monitoraggio è abbastanza versatile grazie all'intercambiabilità dei componenti. Alcuni gestiscono e ampliano costantemente la propria infrastruttura specificamente per Graphite, mentre noi abbiamo deciso di seguire un'altra strada: utilizzare ClickHouse come archivio per le nostre metriche. Questo passaggio è praticamente completato e presto racconterò nel dettaglio come è stato realizzato: quali difficoltà abbiamo incontrato e come le abbiamo superate, come è avvenuto il processo di migrazione, descriverò i componenti scelti come raccordo e le loro configurazioni.

Grazie per l'attenzione! Fate le vostre domande sull'argomento, cercherò di rispondere qui o nei prossimi post. Potrebbe esserci qualcuno con esperienza nella costruzione di un sistema di monitoraggio simile o nel passaggio a Clickhouse in situazioni analoghe — condividete le vostre esperienze nei commenti.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster