Microservizi in fase avanzata
Ho letto dello sforzo del team di Amazon Prime Video per ridimensionare e ridurre i costi del 90% combinando i loro microservizi in un monolite. Mentre sono sicuro che qui c'è di più nella storia, ci sono storie simili pubblicate su Internet; una sorta di confutazione alla mania dei microservizi dell'ultimo decennio.
Mi ha ricordato gli ultimi anni trascorsi su Twitter, dove il numero di microservizi (a migliaia) ha raggiunto il picco e poi ha iniziato a diminuire, anche se il traffico è aumentato. Tutti i tipi di logica applicativa sono stati assorbiti in piattaforme gestite monolitiche di un tipo o dell'altro. Il principio della creazione di microservizi appositamente creati non è intrinsecamente buono e, dopo un certo punto, non sembrava essere un ROI positivo nemmeno per molti dei nostri team.
Un'architettura di microservizi può essere costosa. Nell'ultimo decennio si è diffusa la narrazione secondo cui questa è una politica naturale per le grandi organizzazioni di ingegneria, perché:
- I team possono eseguire iterazioni sui loro servizi in autonomia dall'organizzazione più ampia e dal suo codice
- Piccoli componenti dell'architettura di servizio possono essere modificati senza interrompere il sistema più grande
- L'architettura consente la definizione di domini applicativi e di errore chiari e gestibili tramite servizi indipendenti
- L'architettura consente carichi di lavoro regolabili o scalabili in modo indipendente
Bisogna tenere conto della complessità del lavoro che viene scaricato su piccoli team proprietari di servizi e di conseguenza sull'ecosistema più ampio, in contrasto con un numero singolare o ridotto di monoliti. Il lavoro scaricato dipende dalla maturità dello stack tecnologico dell'organizzazione; ma può includere:
Responsabilità operative e spese generali distribuite tra tutti i team proprietari dei servizi
- La comprensione e la configurazione dei componenti dell'infrastruttura di servizio dalla pianificazione dei lavori e dagli strumenti di implementazione, rilevamento dei servizi, framework RPC, macchine virtuali e messa a punto associata, monitoraggio e registrazione dei servizi
- Definizioni distribuite e processi di sviluppo per SLO e SLI, guasto del servizio e gestione dei guasti, gestione della contropressione e segnalazione degli errori
- Pianificazione della capacità distribuita e spesso non coordinata, test di carico, implementazione e responsabilità dei test di integrazione
- La logica dell'applicazione che interagisce con molti servizi di back-end naviga spesso in una serie di definizioni API di servizi su misura, semantica, modelli di dati, sistemi di controllo delle versioni e occasionalmente anche protocolli diversi
- Gli ingegneri devono comprendere e ragionare sull'architettura complessiva del servizio e sui modelli di traffico per costruire elementi funzionali
- Soluzioni alternative organiche per percorsi di servizio non ottimali o con colli di bottiglia, replica e consumo di dati distribuiti, dipendenze di richieste circolari
- Approcci localizzati a problemi di inferenza e classificazione, elaborazione di eventi, traduzione API HTTP/protocollo interno e mappatura di modelli di dati
- Frammentazione generale e difficoltà a mantenere gli standard in tutto lo stack
Il problema è che il processo di creazione, realizzazione e operatività di un nuovo servizio è costoso . L'integrazione di quel servizio nell'architettura di servizio della produzione è difficile. L'attenzione richiesta per mettere a punto un altro servizio per un funzionamento efficiente; impostare gli account di servizio corrispondenti, i profili di osservabilità e registrazione, i test di integrazione, la rotazione delle chiamate e tutto il resto non fa che aumentare il sovraccarico operativo e di manutenzione del team. La maggior parte delle organizzazioni non dispone di automazione e ponteggi end-to-end per questo tipo di lavoro complesso.
Questo sovraccarico è un grande disincentivo per i team ad attenersi al principio dell'architettura dei microservizi ispirato a UNIX di " fare bene una cosa ". È solo più semplice creare nuovi casi d'uso nei servizi esistenti. All'estremo estremo dello spettro, i team gestiscono servizi "macro" che iniziano a incapsulare tutto ciò di cui sono responsabili come team, che potrebbe includere una varietà di prodotti o funzionalità. La qualità della proprietà diminuisce nel tempo, poiché le riorganizzazioni sono un evento relativamente comune. Stai lavorando con una palla di fango.
Le interruzioni del servizio macro non sono limitate a un set di funzionalità specifico, ma piuttosto a un'area imprevedibile o senza principi del sistema, che potrebbe assomigliare a organigrammi storici. Il sito può o meno tollerare che questi servizi non siano disponibili. È più difficile ottimizzare i servizi per carichi di lavoro eterogenei; i percorsi di chiamata non possono essere districati. Un ex collega ha coniato questo "il microlito".
I microservizi codificano e incentivano l'ottimizzazione locale nell'architettura di servizio. È difficile ritenere i team responsabili di un progetto di principio per servire l'architettura quando l'obiettivo è la federazione dello sviluppo del servizio. Allo stesso modo, è difficile risolvere i problemi di ottimizzazione a livello di back-end quando le proprietà dei servizi dipendenti sono personalizzate. Senza un'architettura di servizio attentamente progettata e piattaforme di servizi di supporto, è difficile trovare un vantaggio: il codice della piattaforma del prodotto riutilizzabile è sparso in una serie di servizi di grandi dimensioni o librerie condivise ; i servizi di frontend di solito su misura.
La leva dei microservizi è stata trovata a livello di elaborazione (qualunque cosa stia orchestrando ed eseguendo job o container di servizio), scoperta di servizi, VM (applicabile in determinati contesti), framework di servizi (come gRPC , Finagle o Rest.Li ) e strumenti di sviluppo centralizzati . Naturalmente, le mesh di servizi incapsulano bene alcune di queste preoccupazioni.
Un altro modo per affrontare questi problemi è ridurre il sovraccarico funzionale. Quindi, piuttosto che cercare di ridurre il ripetuto sovraccarico dell'infrastruttura dovuto all'esecuzione del servizio , puoi ridurre i costi dei team che reimplementano classi di lavoro comuni . Questo è il motivo per cui le piattaforme gestite hanno così tanto successo: anche se la creazione o la gestione di un servizio è costosa, se possiamo assottigliare la sua logica applicativa esternalizzando a una piattaforma gestita pubblica o privata, diventa meno onerosa per il suo team proprietario.
È importante che le organizzazioni valutino attentamente i compromessi dell'architettura in base alle esigenze specifiche, agli obiettivi e alla maturità dello stack tecnologico. I microservizi offrono alcuni vantaggi. Introducono anche complessità e spese generali operative che all'inizio sembrano gestibili, ma si aggravano nel tempo. L'incapacità di affrontare questi problemi rende il processo di sviluppo end-to-end un po' più semplice che lavorare in un monolite.
Alcune cose da tenere a mente, specialmente se stai lavorando con un microlite legacy:
- I "grandi servizi" oi monoliti non sono necessariamente cattivi; richiedono un diverso tipo di strumenti, supporto infra e insieme di principi rispetto ai microservizi, ma dovrebbero essere costruiti per acquisire elementi comuni ben definiti dell'architettura di servizio
- Sostenere il principio "un'attività, un servizio" tende ad essere molto meno pratico che tracciare confini intuitivi attorno ad aree di stretta collaborazione, problemi di prestazioni e domini di errore distinti e spingere i team a rispettare il piano
- È possibile alleviare le complessità e il sovraccarico di "troppi servizi" riducendo la profondità verticale dello stack di cui sono responsabili i proprietari dei servizi (framework di servizi, mesh di servizi, elaborazione), nonché l'estensione dello spazio applicativo attraverso servizi gestiti o piattaforme per flussi di lavoro comuni