Blocchi costruttivi di applicazioni distribuite. Prima approssimazione

Blocchi costruttivi di applicazioni distribuite. Prima approssimazione

Il mondo non si ferma. Il progresso genera nuove sfide tecnologiche. In conformità con le nuove esigenze, deve evolvere anche l'architettura dei sistemi informativi. Oggi parleremo dell'architettura orientata agli eventi, della concorrenza, della parallelità, dell'assincronicità e di come in Erlang sia possibile vivere in armonia con tutto ciò.

Introduzione

A seconda delle dimensioni del sistema progettato e delle sue esigenze, noi sviluppatori scegliamo il modo di scambiare informazioni all'interno del sistema. Nella maggior parte dei casi, per organizzare l'interazione dei servizi, una soluzione valida può essere uno schema con un broker, ad esempio basato su RabbitMQ o Kafka. Ma a volte il flusso di eventi, il SLA e il livello di controllo sul sistema sono tali che un messaging preconfezionato non è adatto. Certo, si può complicare un po' il sistema, assumendo la responsabilità per il livello di trasporto e la creazione di un cluster, ad esempio utilizzando ZeroMQ o nanomsg. Ma se il sistema ha sufficienti capacità di throughput e funzionalità del cluster Erlang standard, la questione di aggiungere un'entità supplementare richiede uno studio approfondito e una giustificazione economica.

Il tema delle applicazioni distribuite reattive è piuttosto ampio. Per rientrare nel formato dell'articolo, l'oggetto della discussione di oggi saranno solo ambienti omogenei costruiti su Erlang/Elixir. L'ecosistema Erlang/OTP permette di realizzare un'architettura reattiva con il minimo sforzo. Ma in ogni caso avremo bisogno di uno strato di scambio di messaggi.

Fondamenti teorici

La progettazione inizia con la definizione degli obiettivi e delle limitazioni. L'obiettivo principale non è quello di sviluppare per il gusto di farlo. Abbiamo bisogno di uno strumento sicuro e scalabile, su cui sia possibile creare, e soprattutto - sviluppare, moderne applicazioni di vari livelli: partendo da quelle monoposto, che servono un pubblico limitato, e che possono in seguito evolversi in cluster fino a 50-60 nodi, fino a federazioni di cluster. Così, l'obiettivo principale è massimizzare il profitto riducendo il costo di sviluppo e di proprietà del sistema finale.

Indichiamo 4 requisiti principali per il sistema finale:

  • Corientamento agli eventi.
    Il sistema è sempre pronto a far passare un flusso di eventi e ad eseguire le azioni necessarie;
  • Mscalabilità.
    I singoli blocchi possono scalare sia verticalmente che orizzontalmente. L'intero sistema deve avere la possibilità di crescita orizzontale infinita;
  • Otolleranza agli errori.
    Tutti i livelli e tutti i servizi devono avere la possibilità di recupero automatico in caso di malfunzionamenti;
  • Gtempo di risposta garantito.
    Il tempo è prezioso e gli utenti non dovrebbero aspettare troppo a lungo.

Ricordate la vecchia favola de “Il piccolo motore che poteva”, noto anche come “Il locomotore che ce l'ha fatta”? Affinché il sistema progettato possa superare con successo la fase di prototipo e diventare progressivo, le sue basi devono soddisfare i requisiti minimi. CE L'HA FATTA.

Al messaging come strumento infrastrutturale e base per tutti i servizi si aggiunge un altro aspetto: l'usabilità per i programmatori.

Orientamento agli eventi

Affinché l'applicazione possa crescere da una server fino a un cluster, la sua architettura deve garantire una debole interconnessione. Questa esigenza è soddisfatta dal modello asincrono. In esso, il mittente e il destinatario si occupano del carico informativo del messaggio e non si preoccupano della trasmissione e del routing all'interno del sistema.

Scalabilità

La scalabilità e l'efficienza del sistema vanno di pari passo. I componenti dell'applicazione devono saper utilizzare tutte le risorse disponibili. Maggiore è l'efficienza con cui possiamo utilizzare le capacità e più ottimali sono i nostri metodi di elaborazione, minori saranno i costi per l'hardware.

All'interno di una singola macchina, Erlang crea un ambiente altamente concorrente. Il bilanciamento tra concorrenza e parallelismo può essere impostato scegliendo il numero di thread del sistema operativo disponibili per l'Erlang VM e il numero di schedulatori che utilizzano questi thread.
I processi Erlang non hanno uno stato condiviso e funzionano in modalità non bloccante. Questo consente una latenza relativamente bassa e una maggiore capacità rispetto alle applicazioni tradizionali basate su sincronizzazione bloccante. Lo schedulatore Erlang si occupa di una distribuzione equa della CPU e dell'I/O, e l'assenza di blocchi consente all'applicazione di rispondere anche in situazioni di carico elevato o di guasti.

A livello di cluster, anche il problema dell'uso delle risorse esiste. È importante che tutte le macchine nel cluster siano equamente caricate e che la rete non sia sovraccarica. Immaginiamo una situazione: il traffico degli utenti arriva ai bilanciatori in entrata (haproxy, nginx, ecc.), che distribuiscono il più uniformemente possibile le richieste da elaborare tra un insieme di backend disponibili. All'interno dell'infrastruttura dell'applicazione, il servizio che realizza l'interfaccia richiesta è solo l'ultima miglio e avrà bisogno di richiedere una serie di altri servizi per rispondere alla richiesta iniziale. Anche le richieste interne richiedono un'adeguata instradamento e bilanciamento.
Per gestire in modo efficace i flussi di dati, il messaging deve fornire agli sviluppatori un'interfaccia per gestire l'instradamento e la distribuzione del carico. In questo modo, gli sviluppatori possono, utilizzando modelli di microservizi (aggregator, proxy, chain, branch, ecc.), affrontare sia compiti standard che quelli che si presentano raramente.

Dal punto di vista aziendale, la scalabilità è uno degli strumenti di gestione dei rischi. È fondamentale soddisfare le richieste dei clienti, ottimizzando l'uso delle attrezzature:

  • Con un aumento della potenza delle attrezzature a causa del progresso, non rimarranno inattive a causa delle imperfezioni del software. Erlang scala bene verticalmente e sarà sempre in grado di utilizzare tutti i core della CPU e la memoria disponibile;
  • Nei contesti di ambienti cloud, possiamo gestire il numero di attrezzature in base al carico attuale o previsto e garantire SLA.

Resilienza

Consideriamo due assiomi: "I guasti non sono tollerabili" e "I guasti ci saranno sempre". Per un'azienda, un guasto del software significa perdita di denaro e, peggio ancora, danno alla reputazione. Bilanciando tra possibili perdite e i costi dello sviluppo di software affidabile, spesso si può trovare un compromesso.

Nel breve termine, un'architettura che prevede l'affidabilità consente di risparmiare denaro sull'acquisto di soluzioni di clustering pronte. Queste sono costose e presentano anch'esse dei bug.
Nel lungo periodo, un'architettura resistente agli errori ripaga più volte i costi del suo utilizzo in tutte le fasi dello sviluppo.
La messaggistica all'interno del codice è ancora in fase di sviluppo e consente di lavorare a fondo sull'interazione dei componenti all'interno del sistema. Ciò semplifica il compito di reazione e gestione dei guasti, poiché tutti i componenti responsabili gestiscono i guasti e il sistema finale sa come tornare automaticamente in uno stato operativo dopo un guasto by design.

Reattività

Indipendentemente dai guasti, l'applicazione deve rispondere alle richieste e soddisfare gli SLA. La realtà è che le persone non vogliono aspettare, quindi il business deve adattarsi. Sempre più applicazioni si aspettano un'alta reattività.
Le applicazioni reattive funzionano in modalità quasi in tempo reale. Erlang VM opera in modalità di soft real-time. Per alcuni settori, come il trading azionario, la medicina, la gestione delle attrezzature industriali, è importante la modalità di hard real-time.
I sistemi reattivi migliorano l'UX e sono utili per il business.

Risultato preliminare

Pianificando questo articolo, volevo condividere l'esperienza di creare un broker di messaggi e costruire sistemi complessi su di esso. Tuttavia, la parte teorica e motivazionale è risultata piuttosto ampia.
Nella seconda parte dell'articolo parlerò delle sfumature nell'implementazione dei punti di scambio, dei modelli di messaggistica e del loro utilizzo.
Nella terza parte esamineremo questioni generali sull'organizzazione dei servizi, il routing e il bilanciamento. Parleremo dell'aspetto pratico della scalabilità e della resilienza dei sistemi.

Fine della prima parte.

Foto @lucabravo.

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