19 settembre a Mosca il primo meetup tematico HUG (Highload++ User Group), dedicato ai microservizi. Durante l'evento è stata presentata la relazione "Gestione dei microservizi: la dimensione conta, anche se hai Kubernetes", in cui abbiamo condiviso l'ampia esperienza dell'azienda "Flant" nella gestione di progetti con architettura a microservizi. Sarà particolarmente utile per tutti gli sviluppatori che stanno considerando di adottare questo approccio nei loro progetti attuali o futuri.

Presentiamo (50 minuti, molto più informativo di un articolo) e anche un riassunto testuale principale.
NB: Il video e la presentazione sono disponibili anche alla fine di questa pubblicazione.
Introduzione
Di solito, una buona storia ha un'introduzione, un conflitto principale e una conclusione. Questa relazione somiglia più a un'introduzione, e per di più tragica. È importante sottolineare che offre anche una visione dei microservizi dal punto di vista di sfruttamento.
Inizierò con questo grafico, la cui autore è (nel 2015) Martin Fowler:

Si può osservare come, nel caso di un'applicazione monolitica che ha raggiunto una certa dimensione, inizi a diminuire la produttività. I microservizi si distinguono per il fatto che la loro produttività iniziale è più bassa, tuttavia, con l'aumento della complessità, la degradazione dell'efficacia non è così evidente.
Integrerò questo grafico per il caso d'uso di Kubernetes:

Perché un'applicazione con microservizi ha avuto un miglioramento? Perché questa architettura presenta requisiti rigorosi che sono eccellentemente soddisfatti dalle capacità di Kubernetes. D'altra parte, parte di questa funzionalità sarà utile anche per il monolite, soprattutto considerando che il monolite tipico attuale non è propriamente un monolite (i dettagli seguiranno nel rapporto).
Come si può vedere, il grafico finale (con applicazioni sia monolitiche che microservizi nell'infrastruttura Kubernetes) non differisce molto dall'originale. In seguito si parlerà di applicazioni gestite utilizzando Kubernetes.
Microservizi utili e dannosi
E qui la idea principale:

Che cos'è normale L'architettura a microservizi? Deve offrirvi un reale valore, aumentando l'efficienza del lavoro. Se torniamo al grafico, eccola qui:

Se la chiamiamo utile, dall'altra parte del grafico ci sarà dannosa microservizialità (ostacola il lavoro):

Tornando al «concetto principale»: dovrei fidarmi della mia esperienza? Dall'inizio di quest'anno ho esaminato 85 progetti. Non tutti erano a microservizi (circa un terzo o metà di essi avevano tale architettura), ma è comunque un numero significativo. Noi (l'azienda «Flant») come fornitori di outsourcing riusciamo a vedere una vasta gamma di applicazioni sviluppate sia in piccole aziende (con 5 sviluppatori) che in grandi (~500 sviluppatori). Un ulteriore vantaggio è che vediamo come queste applicazioni vivono e si evolvono nel corso degli anni.
Perché i microservizi?
La risposta alla domanda sui benefici dei microservizi è secondo l'ormai citato Martin Fowler:
- confini modulari chiari;
- deploy indipendente;
- libertà di scelta delle tecnologie.
Ho parlato molto con architetti e sviluppatori di software, chiedendo loro perché avessero bisogno dei microservizi. Ho creato la mia lista delle loro aspettative. Ecco cosa è emerso:

Se descriviamo «nelle sensazioni» alcuni dei punti, allora:
- confini chiari dei moduli: abbiamo un terribile monolite e ora tutto sarà ben organizzato nei repository Git, dove tutto è «a posto», senza mescolare caldo con freddo;
- indipendenza del deployment: potremo rilasciare i servizi in modo indipendente, accelerando lo sviluppo (pubblicando nuove funzionalità in parallelo);
- indipendenza nello sviluppo: possiamo assegnare questo microservizio a un team/sviluppatore, e quell’altro a un altro, il che ci consente di sviluppare più rapidamente;
- bunmaggiore affidabilità: se si verifica una parziale degradazione (un microservizio su 20 va giù), funzionerà solo un pulsante, mentre il sistema continuerà a operare nel suo insieme.
Architettura microservizi tipica (dannosa)
Per spiegare perché in realtà le cose non sono come ci aspettiamo, presenterò un'immagine collettiva dell'architettura microservizi, basata sull'esperienza di numerosi progetti diversi.
Un esempio sarà un negozio online astratto che mira a competere con Amazon o almeno OZON. La sua architettura a microservizi appare così:

Per un insieme di motivi, questi microservizi sono scritti su piattaforme diverse:

Poiché ogni microservizio deve essere autonomo, molti di essi necessitano di un proprio database e di una cache. L'architettura finale risulta essere la seguente:

Quali sono le sue conseguenze?
Fowler, a questo proposito sulla "penale" per l'uso dei microservizi:

E noi vedremo se le nostre aspettative si sono avverate.
Confini chiari dei moduli…
Ma quanti microservizi dobbiamo realmente sistemare, per rilasciare una modifica? Possiamo davvero capire come funziona tutto senza un tracciatore distribuito (dato che ogni richiesta è elaborata da metà dei microservizi)?
Esiste un pattern del "", e qui si è addirittura creato un groviglio distribuito di fango. A conferma di ciò, ecco un'illustrazione approssimativa di come scorrono le richieste:

Indipendenza del deployment…
Tecnicamente è possibile: possiamo implementare ogni microservizio singolarmente. Ma nella pratica, dobbiamo tenere in considerazione che vengono sempre rilasciati numerosi microservizi, e dobbiamo considerare l'ordine di rilascio. Idealmente, dovremmo testare in un contesto separato per assicurarci che il rilascio avvenga nell'ordine corretto.
Libertà nella scelta della tecnologia…
Esiste. Tuttavia, bisogna ricordare che spesso la libertà confina con l'anarchia. È molto importante non scegliere le tecnologie solo per 'giocare' con esse.
Indipendenza dello sviluppo…
Come creare un contesto di test per l'intera applicazione (con così tanti componenti)? E bisogna anche mantenerlo aggiornato. Tutto ciò porta al fatto che il numero reale di contesti di test, che possiamo effettivamente gestire, risulta essere minimo..
E per implementare tutto questo in locale? Risulta che spesso lo sviluppatore svolge il proprio lavoro in modo indipendente, ma 'alla cieca', poiché è costretto ad aspettare che si liberi un contesto per i test.
Scalabilità separata…
Sì, ma è limitato per quanto riguarda i DBMS utilizzati. Nell'esempio fornito, non ci sarebbero problemi con Cassandra, ma ci sarebbero con MySQL e PostgreSQL.
Bunmaggiore affidabilità…
Non solo il guasto di un singolo microservizio può spesso compromettere il corretto funzionamento dell'intero sistema, ma c'è anche un nuovo problema: rendere ogni microservizio resiliente è molto difficile.Perché nei microservizi vengono utilizzate tecnologie diverse (memcache, Redis, ecc.), e per ognuna bisogna progettare e implementare tutto, il che è certamente possibile, ma richiede risorse enormi.
Misurabilità del carico…
Con questo siamo davvero a posto.
La «leggerezza» dei microservizi…
Non solo abbiamo ora enormi sovraccarichi di rete (le richieste DNS, ecc. si moltiplicano), ma a causa di numerosi sottoquery abbiamo iniziato a replicare i dati (memorizzare le cache), il che ha portato a un notevole volume di archiviazione.
Ecco qual è il risultato rispetto alle nostre aspettative:

Ma non è tutto!
Perché:
- Probabilmente avremo bisogno di un bus di messaggi.
- Come fare un backup consistente in un momento specifico? L'unico reale L'opzione — disattivare il traffico per questo. Ma come farlo in produzione?
- Quando si parla di supportare più regioni, organizzare la resilienza in ciascuna di esse è un compito molto impegnativo.
- Sorge il problema di apportare modifiche centralizzate. Ad esempio, se dobbiamo aggiornare la versione di PHP, sarà necessario fare un commit in ogni repository (e ce ne sono decine).
- La crescita della complessità operativa risulta esponenziale.
Cosa fare con tutto questo?
Iniziate con un'applicazione monolitica. L'esperienza di Fowler suggerisce che praticamente tutte le applicazioni microservizio di successo sono iniziate come monoliti, che sono diventati troppo grandi e sono stati poi suddivisi. Allo stesso tempo, praticamente tutti i sistemi costruiti come microservizi fin dall'inizio hanno affrontato seri problemi, prima o poi.
Un'altra idea preziosa è che, affinché un progetto con architettura microservizi sia di successo, è necessario avere una buona conoscenza sia del dominio che di come realizzare microservizi. E il modo migliore per conoscere il dominio è realizzare un monolito.
Ma cosa fare se ci troviamo già in questa situazione?
Il primo passo per risolvere qualsiasi problema è riconoscerlo e capire che è un problema, che non vogliamo più soffrire.
Nel caso di un monolite cresciuto (quando abbiamo esaurito la possibilità di aggiungere risorse), lo suddividiamo; ma in questo caso si tratta esattamente dell'opposto: quando un'eccessiva microservizialità non aiuta più ma ostacola — tagliate il superfluo e consolidate!
Ad esempio, per l'immagine collettiva considerata sopra…
Eliminate i microservizi più discutibili:

Unite tutti i microservizi responsabili per la generazione del frontend:

… in un unico microservizio, sviluppato in un linguaggio/framework (moderno e affidabile, come ritenete voi) che sia:

Avrà un solo ORM (un solo DBMS) e inizialmente un paio di applicazioni:

… e in effetti si possono trasferire molte più funzioni, ottenendo un risultato simile:

In Kubernetes, avviamo tutto questo come istanze separate, il che significa che possiamo comunque misurare il carico e scalare separatamente.
In sintesi
Considerate la situazione in modo più ampio. Spesso, tutti questi problemi con i microservizi sorgono perché qualcuno ha preso il proprio compito ma voleva "giocare con i microservizi".
Nella parola «microservizi», la parte «micro» è superflua.Sono «micro» solo perché più piccoli di un enorme monolite. Ma non bisogna pensarli come qualcosa di ridotto.
E per concludere, torniamo al grafico originale:

La nota scritta per essa (in alto a destra) si riassume nel fatto che le competenze del team che realizza il vostro progetto sono sempre primarie − sono proprio loro a giocare un ruolo chiave nella vostra scelta tra microservizi e monolite. Se il team non ha le competenze necessarie, ma inizia a realizzare microservizi, la storia sarà sicuramente fatale.
Video e slide
Il video della presentazione (~50 minuti; purtroppo non trasmette le numerose emozioni dei partecipanti, che in gran parte hanno definito l'atmosfera della conferenza, ma tant'è):

Presentazione della relazione:
P.S.
Altre presentazioni nel nostro blog:
- «» (Dmitry Stolyarov; 28 maggio 2018 a RootConf);
- «» (Dmitry Stolyarov; 7 novembre 2017 a HighLoad++);
- «» (Dmitry Stolyarov; 6 giugno 2017 a RootConf);
- «» (Dmitrij Stolyarov; 8 novembre 2016 a HighLoad++);
- «» (Dmitrij Stolyarov; 31 maggio 2016 a RootConf).
Probabilmente potrebbero interessarvi anche le seguenti pubblicazioni:
- «»;
- «»;
- «».
Fonte: habr.com
