
In questo articolo sono raccolti alcuni modelli generali che aiutano gli ingegneri a lavorare con servizi su larga scala a cui accedono milioni di utenti.
Dall'esperienza dell'autore, questa non è una lista esaustiva, ma sono davvero consigli efficaci. Quindi, cominciamo.
Tradotto con il supporto di .
Livello base
Le misure elencate di seguito sono relativamente semplici da implementare, ma offrono un alto ritorno. Se non le avete mai adottate prima, rimarrete sorpresi dai miglioramenti significativi.
Infrastruttura come codice
La prima parte dei consigli consiste nell'implementare l'infrastruttura come codice. Questo significa che dovete avere un modo programmatico per distribuire tutta l'infrastruttura. Suona complicato, ma in realtà stiamo parlando del seguente codice:
Distribuzione di 100 macchine virtuali
- con Ubuntu
- 2 GB di RAM ciascuna
- avranno il seguente codice
- con queste impostazioni
Potete monitorare le modifiche all'infrastruttura e tornare ad esse rapidamente utilizzando un sistema di gestione delle versioni.
Il modernista in me dice che si può utilizzare Kubernetes/Docker per fare tutto quanto sopra, e ha ragione.
Inoltre, l'automazione può essere garantita utilizzando Chef, Puppet o Terraform.
Integrazione e consegna continue
Per creare un servizio scalabile è importante avere una pipeline di build e test per ogni pull request. Anche se il test è il più semplice, garantisce almeno che il codice che distribuite venga compilato.
Ogni volta in questo passaggio rispondete alla domanda: la mia build si compila e passa i test, è valida? Potrebbe sembrare una soglia bassa, ma risolve molti problemi.

Non c'è niente di più bello che vedere questi segni di spunta
Per questa tecnologia potete considerare Github, CircleCI o Jenkins.
Bilanciatori di carico
Quindi, vogliamo avviare un bilanciatore di carico per reindirizzare il traffico e garantire un carico uniforme su tutti i nodi o il funzionamento del servizio in caso di guasto:

Il bilanciatore di carico è generalmente molto utile per distribuire il traffico. La migliore pratica è l'eccessiva bilanciatura, così da non avere un singolo punto di guasto.
Di solito i bilanciatori di carico vengono configurati nel cloud che si sta utilizzando.
RayID, ID di correlazione o UUID per le richieste
Ti è mai capitato di incontrare un errore nell'app con un messaggio del tipo: «Qualcosa è andato storto. Salva questo id e invialo al nostro supporto»?

Un identificatore unico, correlation ID, RayID o qualsiasi variante è un identificatore unico che consente di tracciare la richiesta durante il suo ciclo di vita. Questo permette di seguire l'intero percorso della richiesta nei log.

L'utente effettua una richiesta al sistema A, poi A si collega a B, B si collega a C, salva in X e infine la richiesta torna ad A.
Se ti collegassi da remoto alle macchine virtuali e cercassi di tracciare il percorso della richiesta (e di associare manualmente quali chiamate avvengono), impazziresti. Avere un identificatore unico semplifica notevolmente la vita. È una delle cose più semplici che puoi fare per risparmiare tempo man mano che il servizio cresce.
Livello medio
Qui i consigli sono più complessi rispetto ai precedenti, ma gli strumenti giusti semplificano il compito, garantendo un ritorno sugli investimenti anche per piccole e medie imprese.
Registrazione centralizzata
Congratulazioni! Hai distribuito 100 macchine virtuali. Il giorno dopo, il CEO arriva e si lamenta di un errore che ha ricevuto durante il test del servizio. Riporta l'identificatore pertinente di cui abbiamo parlato sopra, ma dovrai esaminare i log di 100 macchine per trovare quella che ha causato il guasto. E devi trovarla prima della presentazione di domani.
Anche se sembra un'avventura divertente, è meglio assicurarsi di avere la possibilità di cercare in tutti i log da un unico posto. Ho risolto il problema della centralizzazione dei log usando le funzionalità integrate del stack ELK: qui viene supportata la raccolta dei log con la possibilità di ricerca. Questo aiuterà davvero a risolvere il problema di trovare un log specifico. Come bonus, puoi creare diagrammi e altre cose divertenti.

Funzionalità del stack ELK
Agenti di monitoraggio
Ora che il tuo servizio è operativo, devi assicurarti che funzioni senza problemi. Il modo migliore per farlo è avviare alcuni agenti, che operano in parallelo e controllano che funzioni e che vengano eseguite le operazioni di base.
In questa fase verifichi che la build avviata si sente bene e funziona normalmente.
Per progetti piccoli e medi, ti consiglio Postman per il monitoraggio e la documentazione delle API. Ma in generale, è importante assicurarsi di avere un modo per sapere quando si verifica un guasto e ricevere notifiche tempestive.
Autoscaling in base al carico
È molto semplice. Se hai una macchina virtuale che gestisce le richieste e si avvicina al 80% di utilizzo della memoria, puoi aumentare le sue risorse o aggiungere più macchine virtuali nel cluster. L'automazione di queste operazioni è ideale per la scalabilità elastica in base al carico. Ma dovresti sempre prestare attenzione a quanto spendi e impostare limiti ragionevoli.

Nella maggior parte dei servizi cloud, puoi configurare il ridimensionamento automatico utilizzando un numero maggiore di server o server più potenti.
Sistema di esperimenti
Un buon modo per implementare aggiornamenti in sicurezza è avere la possibilità di testare qualcosa per l'1% degli utenti per un'ora. Hai sicuramente visto questi meccanismi in azione. Ad esempio, Facebook mostra a parti del pubblico un colore diverso o modifica la dimensione del font per vedere come gli utenti percepiscono le modifiche. Questo si chiama A/B testing.
Anche il rilascio di una nuova funzionalità può essere avviato come esperimento, e poi puoi decidere come rilasciarla. In questo modo, hai anche la possibilità di "richiamare" o modificare la configurazione al volo in caso di una funzionalità che degrada il tuo servizio.
Livello avanzato
Qui ci sono consigli che sono piuttosto difficili da attuare. Probabilmente avrai bisogno di un po' più di risorse, quindi per una piccola o media impresa sarà difficile gestirli.
Deployments blu-verdi
Questo è ciò che chiamerei un modo "Erlang" di fare deployment. Erlang è diventato ampiamente utilizzato quando sono emerse le compagnie telefoniche. Per il routing delle chiamate telefoniche, sono stati utilizzati switch software. L'obiettivo principale del software di questi switch era quello di non interrompere le chiamate durante l'aggiornamento del sistema. Erlang ha un eccellente modo di caricare un nuovo modulo senza far cadere quello precedente.
Questo passaggio dipende dalla presenza di un bilanciatore di carico. Immagina di avere la versione N del tuo software e poi vuoi distribuire la versione N+1.
Tu potresti semplicemente fermare il servizio e distribuire la versione successiva nel momento che ritieni più opportuno per i tuoi utenti, e avere un certo tempo di inattività. Ma supponiamo che tu abbia in effetti restringenti condizioni SLA. Quindi, un SLA del 99,99% significa che puoi andare offline solo per 52 minuti all'anno.
Se desideri davvero raggiungere tali metriche, hai bisogno di due distribuzioni simultanee:
- quella attuale (N);
- la versione successiva (N+1).
Indichi al bilanciatore di carico di reindirizzare una certa percentuale di traffico alla nuova versione (N+1), mentre tu monitori attivamente le regressioni.

Qui abbiamo una distribuzione verde N che funziona normalmente. Stiamo cercando di passare alla versione successiva di questa distribuzione.
All'inizio inviamo un test molto piccolo per vedere se la nostra distribuzione N+1 funziona con un basso volume di traffico:

Infine, abbiamo un insieme di controlli automatici che eseguiamo fino a quando la nostra distribuzione non è completata. Se sei estremamente attento, puoi anche mantenere la tua distribuzione N per sempre per un rapido rollback in caso di cattiva regressione:

Se desideri passare a un livello ancora più avanzato, lascia che tutto nella distribuzione blu-verde venga eseguito automaticamente.
Rilevamento delle anomalie e mitigazione automatica
Dato che hai un logging centralizzato e una buona raccolta di log, puoi già puntare a obiettivi più alti. Ad esempio, prevedere proattivamente i guasti. Sui monitor e nei log vengono tracciate le funzionalità e vengono create varie grafici – e puoi prevedere in anticipo cosa andrà storto:

Con il rilevamento delle anomalie inizi a esaminare alcuni indizi forniti dal servizio. Ad esempio, un picco del carico della CPU può indicare che il disco rigido sta fallendo, mentre un picco nel numero di richieste significa che è necessario scalare. Questo tipo di dati statistici consente di rendere il servizio proattivo.
Ricevendo tali dati analitici, è possibile scalare in qualsiasi dimensione, modificando proattivamente e reattivamente le caratteristiche di macchine, database, connessioni e altre risorse.
Ecco tutto!
Questa lista di priorità vi salverà da molti problemi se state incrementando il servizio cloud.
L'autore dell'articolo originale invita i lettori a lasciare i propri commenti e a fare modifiche. L'articolo è distribuito come open source, le pull request sono accettate dall'autore .
Ulteriori letture sull'argomento:
Fonte: habr.com
