Elementi costitutivi di applicazioni distribuite. Approssimazione zero

Elementi costitutivi di applicazioni distribuite. Approssimazione zero

Il mondo non si ferma. Il progresso crea nuove sfide tecnologiche. In conformità con le mutevoli esigenze, l'architettura dei sistemi informativi deve evolversi. Oggi parleremo di architettura guidata dagli eventi, concorrenza, concorrenza, asincronia e di come puoi convivere pacificamente con tutto questo a Erlang.

Introduzione

A seconda delle dimensioni del sistema progettato e dei suoi requisiti, noi sviluppatori scegliamo il metodo di scambio delle informazioni nel sistema. Nella maggior parte dei casi, per organizzare l'interazione dei servizi, un'opzione di lavoro può essere uno schema con un broker, ad esempio basato su RabbitMQ o Kafka. Ma a volte il flusso degli eventi, gli SLA e il livello di controllo sul sistema sono tali che la messaggistica già pronta non è adatta a noi. Naturalmente è possibile complicare un po' il sistema assumendosi la responsabilità del livello di trasporto e della formazione dei cluster, ad esempio utilizzando ZeroMQ o nanomsg. Ma se il sistema ha capacità e capacità sufficienti per un cluster Erlang standard, la questione dell'introduzione di un'entità aggiuntiva richiede uno studio dettagliato e una giustificazione economica.

Il tema delle applicazioni distribuite reattive è piuttosto ampio. Per restare nel formato dell'articolo, l'oggetto della discussione di oggi saranno solo gli ambienti omogenei costruiti su Erlang/Elixir. L'ecosistema Erlang/OTP ti consente di implementare un'architettura reattiva con il minimo sforzo. Ma in ogni caso avremo bisogno di un livello di messaggistica.

Base teorica

La progettazione inizia con la definizione di obiettivi e vincoli. L’obiettivo principale non è nell’area dello sviluppo fine a se stesso. Dobbiamo dotarci di uno strumento sicuro e scalabile sulla base del quale creare e, soprattutto, sviluppare applicazioni moderne a vari livelli: partendo da applicazioni a server singolo che servono un pubblico ristretto, che possono successivamente svilupparsi in cluster fino a 50 -60 nodi, che terminano con le federazioni di cluster. Pertanto, l’obiettivo principale è massimizzare i profitti riducendo i costi di sviluppo e proprietà del sistema finale.

Evidenziamo 4 requisiti principali per il sistema finale:

  • Сorientato agli eventi.
    Il sistema è sempre pronto a seguire il flusso degli eventi ed eseguire le azioni necessarie;
  • Мscalabilità.
    I singoli blocchi possono essere ridimensionati sia verticalmente che orizzontalmente. L'intero sistema deve essere capace di crescita orizzontale infinita;
  • Оtolleranza ai guasti.
    Tutti i livelli e tutti i servizi dovrebbero essere in grado di ripristinarsi automaticamente in caso di errori;
  • Гtempo di risposta garantito.
    Il tempo è prezioso e gli utenti non dovrebbero aspettare troppo a lungo.

Ricordi la vecchia fiaba sul "piccolo motore che potrebbe"? Affinché il sistema progettato esca con successo dalla fase di prototipo e sia progressivo, le sue fondamenta devono soddisfare i requisiti minimi SMOG.

Alla messaggistica come strumento infrastrutturale e base di tutti i servizi si aggiunge un ulteriore punto: la facilità d'uso per i programmatori.

Orientato agli eventi

Affinché un'applicazione possa passare da un singolo server a un cluster, la sua architettura deve supportare l'accoppiamento lento. Il modello asincrono soddisfa questo requisito. In esso, il mittente e il destinatario si preoccupano del carico di informazioni del messaggio e non si preoccupano della trasmissione e dell'instradamento all'interno del sistema.

scalabilità

Scalabilità ed efficienza del sistema vanno di pari passo. I componenti dell'applicazione devono essere in grado di utilizzare tutte le risorse disponibili. Quanto più efficientemente riusciamo a utilizzare la capacità e quanto più ottimali sono i nostri metodi di lavorazione, tanto meno denaro spendiamo per le attrezzature.

All'interno di una singola macchina, Erlang crea un ambiente altamente competitivo. L'equilibrio tra concorrenza e parallelismo può essere impostato scegliendo il numero di thread del sistema operativo disponibili per la VM Erlang e il numero di scheduler che utilizzano questi thread.
I processi Erlang non condividono lo stato e operano in modalità non bloccante. Ciò fornisce una latenza relativamente bassa e un throughput più elevato rispetto alle tradizionali applicazioni basate sul blocco. Lo scheduler di Erlang garantisce un'equa allocazione di CPU e IO e l'assenza di blocchi consente all'applicazione di rispondere anche durante picchi di carico o guasti.

A livello di cluster esiste anche il problema dello smaltimento. È importante che tutte le macchine del cluster siano caricate uniformemente e che la rete non sia sovraccarica. Immaginiamo una situazione: il traffico degli utenti arriva sui bilanciatori in entrata (haproxy, nginx, ecc.), distribuiscono le richieste di elaborazione nel modo più uniforme possibile tra l'insieme di backend disponibili. All'interno dell'infrastruttura applicativa, il servizio che implementa l'interfaccia richiesta è solo l'ultimo miglio e dovrà richiedere una serie di altri servizi per rispondere alla richiesta iniziale. Anche le richieste interne richiedono instradamento e bilanciamento.
Per gestire in modo efficace i flussi di dati, la messaggistica deve fornire agli sviluppatori un'interfaccia per gestire il routing e il bilanciamento del carico. Grazie a ciò, gli sviluppatori saranno in grado, utilizzando modelli di microservizi (aggregatore, proxy, catena, ramo, ecc.), di risolvere sia i problemi standard che quelli che si presentano raramente.

Dal punto di vista aziendale, la scalabilità è uno degli strumenti di gestione del rischio. L'importante è soddisfare le richieste del cliente utilizzando in modo ottimale le attrezzature:

  • Quando la potenza dell'attrezzatura aumenta a causa del progresso. Non sarà inattivo a causa del software imperfetto. Erlang scala bene verticalmente e sarà sempre in grado di utilizzare tutti i core della CPU e la memoria disponibile;
  • Negli ambienti cloud, possiamo gestire la quantità di apparecchiature in base al carico attuale o previsto e garantire lo SLA.

tolleranza ai guasti

Consideriamo due assiomi: "I fallimenti sono inaccettabili" e "Ci saranno sempre fallimenti". Per un’azienda, un guasto del software significa perdita di denaro e, quel che è peggio, perdita di reputazione. Trovando un equilibrio tra possibili perdite e il costo di sviluppo di software tollerante ai guasti, spesso è possibile trovare un compromesso.

Nel breve termine, un'architettura che incorpora la tolleranza agli errori consente di risparmiare denaro sull'acquisto di soluzioni di clustering pronte all'uso. Sono costosi e hanno anche bug.
A lungo termine, un’architettura tollerante ai guasti si ripaga molte volte in tutte le fasi dello sviluppo.
La messaggistica all'interno del codebase consente di elaborare in dettaglio l'interazione dei componenti all'interno del sistema in fase di sviluppo. Ciò semplifica il compito di rispondere e gestire i guasti, poiché tutti i componenti critici gestiscono i guasti e il sistema risultante sa come tornare automaticamente alla normalità dopo un guasto in base alla progettazione.

tenerezza

Indipendentemente dagli errori, l'applicazione deve rispondere alle richieste e soddisfare lo SLA. La realtà è che le persone non vogliono aspettare, quindi le aziende devono adattarsi di conseguenza. Si prevede che sempre più applicazioni saranno altamente reattive.
Le applicazioni reattive funzionano quasi in tempo reale. Erlang VM opera in modalità soft real-time. Per alcune aree, come il commercio di azioni, la medicina e il controllo delle apparecchiature industriali, la modalità hard real-time è importante.
I sistemi reattivi migliorano la UX e apportano vantaggi al business.

Risultato preliminare

Durante la pianificazione di questo articolo, volevo condividere la mia esperienza nella creazione di un broker di messaggistica e nella creazione di sistemi complessi basati su di esso. Ma la parte teorica e motivazionale si è rivelata piuttosto ampia.
Nella seconda parte dell'articolo parlerò delle sfumature dell'implementazione dei punti di scambio, dei modelli di messaggistica e della loro applicazione.
Nella terza parte considereremo questioni generali di organizzazione dei servizi, instradamento e bilanciamento. Parliamo del lato pratico della scalabilità e della tolleranza ai guasti dei sistemi.

La fine della prima parte.

foto @lucabravo.

Fonte: habr.com

Aggiungi un commento