genro-asgi · documento 3 di 3

Più macchine: cervello nostro, braccia loro

Come il piano cresce oltre una macchina senza cedere a nessuno la decisione su dove vive una persona — e come si usa Kubernetes prendendone i muscoli e non il giudizio.

Il punto di partenzaUna macchina finisce

Il secondo documento arriva a una conclusione che poi diventa un vincolo: se lo stato di lavoro di una persona vive nella memoria di un processo, allora dove quella persona viene servita è una decisione applicativa, non infrastrutturale. Nessun bilanciatore può prenderla, perché nessun bilanciatore sa cosa sia una persona.

Va benissimo su una macchina. Ma le macchine finiscono: la memoria si esaurisce, i core si esauriscono, e prima o poi il parco deve diventare più di uno. E qui la domanda si fa scomoda: come si cresce su più macchine, se la decisione su dove vive un utente non può essere delegata?

La risposta breve è che non si delega la decisione — si delega l'esecuzione. La distinzione è tutto il contenuto di questo documento.

Come leggere questo documento

Descrive l'architettura distribuita nella sua forma compiuta. La roadmap in appendice dichiara cosa è già operativo e cosa è in corso di implementazione: è l'unica parte che cambia mentre il lavoro procede. Presuppone il secondo documento — lo stato vivo, l'utente come chiave, i gruppi come versioni.

La regolaCervello nostro, braccia sue

C'è una frase che riassume la posizione rispetto a qualunque piattaforma di orchestrazione, Kubernetes compreso: il cervello è nostro, le braccia sono sue.

Le braccia sono quello che una piattaforma fa meglio di noi e che non abbiamo interesse a riscrivere: procurare una macchina, far nascere un processo dentro un confine di risorse, riavviarlo se cade, distribuirlo su nodi diversi, sostituire un nodo morto. È lavoro ingrato, e loro lo fanno bene.

Il cervello è quello che nessuna piattaforma può fare al posto nostro, perché richiede di sapere cosa sia un utente e cosa possieda: quante unità servono, quando servono, chi ci va dentro e quando qualcuno deve essere spostato.

La piattaforma non vede mai un utente. Vede solo processi da far nascere, quando glielo ordiniamo.

Questa non è diffidenza verso Kubernetes: è la constatazione che il suo modello — unità intercambiabili, traffico distribuito su chi è disponibile — è esattamente il modello che il nostro caso d'uso non può adottare. Prenderne le parti giuste è un guadagno; prenderne anche il giudizio significherebbe rompere lo sticky.

La strutturaDue gerarchie che si incrociano

Distribuire introduce una seconda dimensione. Fino a una macchina esisteva solo la versione: quale codice esegue un processo. Con più macchine si aggiunge la capacità: quale ferro lo ospita. Le due dimensioni sono ortogonali — una versione gira su più macchine, una macchina ospita più versioni — e si incrociano esattamente sul processo di lavoro.

Da qui la scelta di avere due gerarchie distinte invece di una sola che tenta di fare entrambi i mestieri:

  • La gerarchia logica, per versione. Il vertice conosce i gruppi; ogni gruppo ha un capogruppo che governa i processi della propria versione, dovunque essi si trovino fisicamente.
  • La gerarchia fisica, per capacità. Il vertice conosce i domini; ogni dominio — una macchina, una fetta di cluster — ha un sub-commander che governa la nascita, la sorveglianza e le risorse dei processi che ospita, di qualunque versione siano.

La conseguenza è che ogni processo di lavoro ha due genitori con due mestieri diversi: il capogruppo, che sa quali utenti gli appartengono e decide il suo destino; e il titolare del dominio fisico, che lo fa nascere, lo sorveglia e ne misura le risorse. Nessuno dei due invade il mestiere dell'altro.

Il vertice utenti · gruppi · budget · arbitraggio PER VERSIONE PER CAPACITÀ capogruppo · stabile decide nascite e spostamenti capogruppo · nuova dentro il proprio budget dominio di casa il vertice stesso sub-commander macchina o fetta di cluster il processo di lavoro appartiene a UN gruppo e vive in UN dominio due genitori, due mestieri distinti

La matrice versione × capacità non è compilata dall'alto: emerge dal basso, come somma delle decisioni dei capigruppo, vincolata dai budget che il vertice assegna e dalla capacità che i domini dichiarano.

Il meccanismoFigli come canali tipizzati

Il vertice tiene i propri figli come canali tipizzati, di due specie: un processo di lavoro che ha generato e sorveglia lui stesso, oppure un sub-commander remoto che si è agganciato. Le due specie possono convivere nello stesso vertice.

IL VERTICE  (utenti, gruppi, budget, giudizio)
├── worker            processo di casa, generato qui
├── worker            processo di casa, generato qui
├── sub-commander     macchina remota  ── worker … worker
└── sub-commander     dominio su cluster ── worker … worker

La proprietà che rende questo disegno sostenibile è che il tipo del canale non produce mai una diramazione nel codice. Chi deve raggiungere un destinatario risolve l'indirizzo, prende il canale, spedisce la busta: lo stesso gesto identico per un processo di casa e per una macchina all'altro capo della rete. Cosa ci sia dietro il canale è una proprietà del dato, non un ramo nella logica.

È lo stesso principio già visto nel ruolo singolo: quando tutto vive in un processo, il canale è una coppia di code in memoria che codifica i messaggi esattamente come farebbe un socket. Un solo protocollo, tre collocazioni — in processo, su un'altra macchina, su una fetta di cluster — e una sola batteria di test di contratto che le verifica tutte, perché due implementazioni della stessa cosa divergono appena qualcosa non le obbliga a restare uguali.

Un sub-commander è il vertice stesso, la stessa classe, con l'indicazione di chi sia il proprio genitore. Non è un componente a parte da mantenere in parallelo: è la stessa macchina montata un livello più in basso.

Una regola sola tiene a bada la complessità: la gerarchia è profonda un livello. Un sub-commander non ha a sua volta sub-commander. Non c'è ricorsione, non ci sono cammini di lunghezza imprevedibile, e non esiste la topologia che nessuno riesce più a disegnare alla lavagna.

Il traffico segue i rami dell'albero: un processo parla al proprio commander, che lo indirizza al canale di destinazione. Non ci sono scorciatoie laterali fra domini — e questa è la ragione per cui i processi di lavoro non si affacciano mai sulla rete: gli unici esposti sono il vertice e i sub-commander.

La chiaveMappa grossa in alto, mappa fine in basso

Il problema più insidioso di un registro distribuito è la duplicazione: se due livelli sanno la stessa cosa, prima o poi divergono, e non c'è modo di stabilire quale dei due abbia ragione.

La soluzione è che i due livelli sanno cose diverse, con precisione diversa:

LivelloCosa saPer decidere
Il verticeutente → indirizzo (un dominio, oppure un processo di casa)dove mandare la richiesta; le domande globali; l'arbitraggio fra gruppi
Il dominioutente → processo, e il carico dei propri processila distribuzione interna: assegnare, ribilanciare, far nascere
Il processoutente → connessioni → pagine, con tutti i contenutieseguire

La mappa fine — quale processo esatto tiene una persona — vive solo dove vivono i processi. Il vertice tiene la mappa grossa: sa che Maria sta nel dominio B, non sa quale processo di B la stia servendo, e non ha bisogno di saperlo.

Quindi la risoluzione è a due tappe, ognuna su un solo livello: il vertice riconosce il dominio e spedisce lì; il dominio risolve il processo e serve. Nessuna ricerca ricorsiva, nessuna cache da invalidare in cascata, e — soprattutto — nessuna verità duplicata: quando il dominio B sposta Maria da un suo processo a un altro, il vertice non ha nulla da aggiornare, perché quello che il vertice sa è ancora vero.

Vale anche per gli aggiornamenti dei dati: una modifica destinata a una pagina che sta altrove risale al vertice, che la indirizza al dominio, che la consegna al processo. Un solo schema per il traffico di controllo e per quello dei dati.

La regola sotto tutte le altre

Un solo scrittore per ogni fatto, e ogni livello sa una cosa più grossa di quello sotto. È ciò che permette a ogni livello di decidere in autonomia senza chiedere permesso: le informazioni non si sovrappongono, quindi non possono contraddirsi.

La divisione dei poteriChi decide, chi arbitra, chi esegue

Un sistema distribuito si rompe quando due componenti credono entrambe di decidere la stessa cosa. Qui i mestieri sono tre, e sono disgiunti — l'immagine è quella di un'azienda con sezioni autonome dentro un budget.

Il capogruppo decide

Guarda l'occupazione dei processi della propria versione e decide: far nascere, ritirare, ricollocare una persona, cambiare la propria versione con un rilascio graduale. Decide da solo, dentro il budget che gli è stato assegnato. Le sezioni hanno vite indipendenti: quello che accade in un gruppo non passa dal cervello di un altro.

Il vertice arbitra

Non micro-decide. Fa tre cose: smista una persona verso il gruppo giusto quando entra; assegna i budget e i massimali di ciascun gruppo, che è il vero arbitraggio del ferro condiviso; governa le operazioni che attraversano i gruppi, come portare una persona da una versione all'altra.

Il sub-commander offre ed esegue

Pubblica la capacità del proprio dominio, materializza le nascite e le morti che i capigruppo ordinano, riferisce la salute di quel che ospita. Non conosce la strategia: non sa perché serva un processo in più, sa come procurarlo.

Questa divisione risponde anche alla domanda pratica di come nasce un nuovo processo quando le risorse si esauriscono, e vale la pena essere precisi su chi tiene la penna, perché è il punto in cui è facile immaginare la catena al contrario.

Non è il processo saturo a chiedere aiuto per sé. Il processo misura e riferisce: quanta memoria sta usando davvero, quanto sono saturi i suoi componenti. Chi legge quelle misure è il capogruppo, che vede l'intera sezione e non un pezzo, e che quindi può distinguere il caso in cui basta spostare qualcuno da quello in cui serve davvero un'unità in più. Se la conclusione è che serve, il capogruppo ordina; il sub-commander del dominio scelto materializza; il processo nuovo nasce, si presenta al proprio commander, e da quel momento è nel giro.

Chi misura non decide, chi decide non esegue, chi esegue non conosce la strategia.

La prova del disegnoIl cliente stagionale

C'è un caso che ha guidato una revisione importante del disegno, e vale la pena raccontarlo perché mostra cosa si guadagna dall'ammettere figli di specie mista.

Un cliente lavora per dieci mesi l'anno su una macchina sola, comodamente. Poi arriva la stagione — la campagna, la chiusura, il picco — e per qualche settimana servono tre macchine. Poi il picco passa.

Una versione precedente del disegno vietava i ruoli doppi: il vertice non poteva possedere processi di lavoro, doveva sempre esserci un livello intermedio. Era coerente, e imponeva una cerimonia costante: anche per la macchina singola servivano tre processi, uno dei quali esisteva solo per rispettare la simmetria.

Ammettendo la specie mista, il caso stagionale diventa una transizione a costo zero. Il vertice possiede i suoi processi di casa; quando arrivano le macchine di picco, la sua tabella comincia a contenere anche voci di dominio remoto; quando il picco passa, quelle voci scompaiono. Il vertice non cambia mai ruolo, non c'è una riconfigurazione, non c'è un momento di migrazione da una topologia all'altra: crescere e restringersi sono la stessa operazione in due direzioni.

E il caso comune — che per la maggior parte dei clienti è l'unico — non paga processi che esistono solo per la coerenza dello schema. Il minimo di sviluppo resta due processi: il vertice e un lavoratore.

La piattaformaKubernetes, preso per le parti giuste

Su un cluster, un dominio di capacità è una fetta di cluster e il sub-commander è il processo che la governa: materializza i processi di lavoro chiamando le API della piattaforma, e quei processi attaccano il proprio canale a lui. La catena non cambia di una virgola — cambia soltanto chi, dietro il canale, ha le mani sul ferro.

La corrispondenza dei concetti

Da noiSul cluster
processo di lavoroun pod, con un solo processo dentro — la forma idiomatica
gruppo, cioè una versioneun Deployment
versione dell'ambientel'immagine del container: sul cluster la domanda «come faccio arrivare il runtime alla macchina» si risponde da sé
capogruppoil controllore del proprio Deployment
dominio di capacitàil sub-commander: un processo che materializza pod via API e a cui i pod si agganciano

Resta possibile, come via di mezzo, il pod che contiene un sub-commander e diversi processi di lavoro insieme — utile in certi assetti, ma non è il disegno primario.

Cosa della piattaforma non usiamo, e perché

Questa è la parte che sorprende chi arriva dal mondo dei container, e sono tre rinunce deliberate. Nessuna è ideologica: ognuna corrisponde a un meccanismo che, applicato a processi che tengono stato, farebbe danno.

MeccanismoPerché non lo usiamo
Il bilanciatore del cluster Distribuisce il traffico su chi è disponibile: è esattamente ciò che non deve accadere. Il traffico degli utenti entra solo dalla nostra porta, e l'inoltro va al pod preciso che il registro indica — non a uno equivalente.
L'autoscaling della piattaforma Scala su metriche che non sanno cosa sia una persona: aggiungerebbe unità guardando la CPU mentre la risorsa che si esaurisce è la memoria di chi sta fermo con un oggetto grosso in pancia. La scala la decide il capogruppo, e la ordina alle API — la piattaforma è pienamente comandabile in modo imperativo, ed è così che la usiamo.
Il rilascio graduale nativo Sostituisce i pod con i propri tempi, ignorando chi ci sta sopra: applicato a processi con stato significa scollegare gli utenti. Il cambio di versione resta la nostra coreografia — porta su il gruppo nuovo, spostagli le persone a caldo, ritira il vecchio quando è vuoto — eseguita chiamando le API.
Ciò che la piattaforma fa comunque, e va digerito

Un cluster prende iniziative fisiche unilaterali: un nodo muore e i suoi pod vengono rischedulati altrove, un pod viene sfrattato perché il nodo serve ad altro. Non si può impedirlo, e non si deve provarci.

Ma non è un dovere nuovo: è lo stesso dovere che abbiamo sul ferro nostro, dove i processi muoiono comunque. Il piano è costruito sul presupposto che un processo possa sparire in qualunque momento — la morte è un canale che si chiude, e ciò che quel processo teneva viene liberato e ricostruito. Su un cluster quel presupposto si verifica più spesso; il meccanismo che lo affronta è identico.

Onestà tecnicaIl costo che abbiamo accettato

Il disegno ha un prezzo dichiarato: il traffico verso un dominio remoto fa un salto in più, perché passa dal vertice al sub-commander e da lì al processo, invece di andare diretto.

È stato accettato con tre ragioni, che vale la pena esporre perché è il tipo di scelta su cui un lettore tecnico vuole vedere i conti:

  • I processi di casa non pagano nulla. Sono figli diretti del vertice: zero salti aggiuntivi. Nel caso più comune — una macchina — il costo semplicemente non esiste.
  • Il salto è dentro il centro dati. Si misura in frazioni di millisecondo, contro i venti o cinquanta millisecondi che separano comunque il browser dal server. È rumore dentro un ritardo che c'è già.
  • Gli eventi si accorpano. Ciò che viaggia verso un dominio remoto viene raggruppato per destinazione, così un aggiornamento destinato a molte pagine dello stesso dominio costa una sola spedizione.

In cambio si ottiene la proprietà che rende il sistema comprensibile: i processi di lavoro non si affacciano sulla rete, il perimetro esposto è fatto di due sole specie di componenti, e il traffico segue l'albero — quindi il cammino di un messaggio è sempre disegnabile.

È registrata come possibile evoluzione, non come impegno, l'ipotesi che su una rete piatta e fidata il solo traffico dei dati possa andare diretto, mantenendo il controllo sull'albero. È un'ottimizzazione che si fa quando i numeri la chiedono, non prima.

La prova del fuocoQuando qualcosa muore

Un'architettura distribuita si giudica da cosa succede quando un pezzo sparisce. Qui i casi sono tre, con raggi di danno diversi e dichiarati.

Muore un processo di lavoro

Il suo canale si chiude, e questo è il segnale: ciò che teneva viene liberato, i permessi che aveva in mano rilasciati, e un sostituto nasce con un nome nuovo — mai riusato, così nessun messaggio in ritardo può essere confuso col nuovo arrivato. Il danno è limitato alle sessioni che quel processo ospitava.

Muore una macchina remota

È un solo canale che si chiude, e questa è la virtù del disegno: il raggio del danno coincide con il dominio. Il vertice cancella dalla propria tabella le voci che puntavano lì, e le persone che vivevano su quella macchina vengono ricollocate sui domini che restano.

Muore la macchina del vertice

Si porta via il cervello, e va detto chiaramente. Ma è un costo di qualunque topologia che ospiti il cervello da qualche parte, non un costo di questo disegno in particolare: il coordinamento sta su una macchina, e quella macchina è un punto singolo. La difesa è la stessa che vale per il caso mono-macchina — la sessione applicativa sopravvive al riavvio, perché lo stato viene raccolto scendendo e ripiazzato risalendo.

Il pannelloCome si guarda un parco

Il pannello del secondo documento guarda i processi e le persone di un pool. Salendo al vertice la vista cambia grana, e cambia per la stessa ragione per cui la tabella degli indirizzi è più grossa: il vertice non sa quale processo serva chi, e non deve saperlo. Guarda domini.

Chi vuole scendere al dettaglio apre il pannello del dominio — che è lo stesso pannello, perché un sub-commander è la stessa cosa del vertice montata un livello più in basso.

I domini

supervisione · domini 4 domini · 1 irraggiungibile · 187 persone DOMINIO CANALE CAPACITÀ PROCESSI PERSONE GRUPPI OSPITATI casa il vertice stesso locale nessun salto 0.58 3 89 stabile · nuova nodo-2 macchina · ferro proprio attivo agganciato 6 g · 0.4 ms 0.71 4 71 stabile cluster-eu fetta di cluster · pod via API attivo agganciato 2 g · 1.1 ms 0.34 6 27 nuova nodo-3 macchina · ferro proprio irraggiungibile caduto 40 s fa — nessuna lettura — 28 persone ricollocate un dominio muto non azzera i suoi numeri: li dichiara mancanti · le sue persone sono già altrove, il raggio del guasto è il dominio

Ogni riga è un canale del vertice. «Casa» è il dominio che il vertice governa direttamente e non paga salti; gli altri sono agganciati, con la latenza del salto in chiaro accanto — quella frazione di millisecondo che è il costo dichiarato del disegno. La capacità è ciò che il dominio offre contro ciò che ha impegnato: è il numero su cui il vertice assegna i budget.

La matrice che emerge dal basso

supervisione · gruppi × domini processi · persone CASA NODO-2 CLUSTER-EU TOTALE GRUPPO stabile 1.4.2 · in svuotamento 2 · 64 sat 0.61 4 · 71 sat 0.71 6 processi · 135 nuova 1.5.0 · in arrivo 1 · 25 sat 0.52 6 · 27 sat 0.34 7 processi · 52 nessuno ha compilato questa griglia: è la somma delle decisioni dei capigruppo, dentro i budget del vertice e la capacità dei domini

Le caselle vuote non sono un errore di configurazione: nessuno ha deciso che «stabile» debba stare sul cluster, e nessuno gliel'ha vietato. Quella casella si riempirà se e quando il capogruppo di «stabile» avrà bisogno di capacità e il cluster sarà il posto migliore per prenderla. È il senso pratico di una matrice che emerge dal basso invece di essere dichiarata.

OsservabilitàIl terzo livello di metriche

I due documenti precedenti descrivono i primi due livelli: il processo che espone se stesso, e il supervisore che ripubblica le letture dei propri processi — raccolte dalla sonda che già gira, perché i processi di lavoro non parlano HTTP.

Con più macchine la stessa forma si ripete di un livello, e questa è la proprietà interessante: il terzo livello non è un meccanismo nuovo. Un sub-commander sta verso i propri processi esattamente come il vertice sta verso i suoi, quindi espone le metriche del proprio dominio nello stesso modo. Il vertice, a sua volta, espone ciò che sa alla propria scala.

E ciò che il vertice sa è deliberatamente più grosso, per la stessa ragione per cui la sua tabella degli indirizzi è più grossa: non tiene un doppione di quello che sanno i domini.

LivelloChi lo esponeLe grandezze
Il processo se stesso, quando serve HTTP; altrimenti risponde al supervisore sul canale traffico e tempi di risposta, pool di lavoro, sessioni e accessi, task nello spool
Il dominio il suo titolare — il vertice per i processi di casa, il sub-commander per gli altri saturazione e memoria di ciascun processo, ampiezza del pool, nascite e ritiri con la causa, spostamenti, traffico dello stato vivo
Il sistema il vertice capacità offerta e impegnata per dominio, distribuzione delle persone fra domini e fra gruppi, budget assegnati e consumati, canali agganciati e loro cadute, operazioni fra gruppi

La raccolta non attraversa la gerarchia: chi raccoglie interroga ogni livello dove è esposto, senza che un livello debba fare da tramite per le metriche di quello sotto. È l'opposto di quel che accade al traffico applicativo, che invece segue i rami dell'albero — e la differenza è voluta, perché il percorso delle metriche non deve poter influenzare le prestazioni di ciò che misura.

Un dominio irraggiungibile non fa cadere la lettura del sistema: risulta come tale, esattamente come nel pannello di supervisione. Un buco nei dati che si dichiara è un'informazione; un buco che passa per zero è un errore.

Cosa si guadagna dallo stesso formato tre volte

Gli allarmi si scrivono una volta sola. «La saturazione di qualcosa è oltre soglia da dieci minuti» ha la stessa forma per un processo, per un pool e per un dominio intero — e la stessa dashboard, cambiando solo l'etichetta, serve il caso mono-macchina e il parco di dieci nodi. Chi cresce non cambia strumenti: cambia solo quante righe legge.

AppendiceRoadmap: dove siamo

Il documento descrive l'architettura distribuita nella sua forma compiuta. Questa appendice è il solo posto dove si legge lo stato di avanzamento.

Il fondamento è già in piedi: il protocollo del canale è nato con due collocazioni — in processo e su socket — e una sola batteria di test di contratto le verifica insieme. È la premessa che rende il sub-commander un'aggiunta e non una riscrittura, perché non introduce un protocollo nuovo: monta quello esistente un livello più in basso.

CapitoloStatoNota
Protocollo del canale con più collocazionioperativoin processo e su socket, verificate dalla stessa batteria di test
Il vertice come titolare del dominio di casaoperativogenera, sorveglia, rilancia, misura
Spostamento a caldo di una persona fra processioperativola primitiva su cui poggia ogni ricollocazione, anche fra domini
Sopravvivenza dello stato al riavviooperativoraccolta allo spegnimento, ripiazzamento all'avvio
Misura delle risorse e giudizio sull'occupazioneoperativosaturazione per componente, memoria misurata onestamente
Canali di specie mista sul verticein implementazioneoggi il vertice tiene processi di casa; l'aggancio di un dominio remoto è il passo che apre il multi-macchina
Sub-commanderin implementazioneè la stessa classe del vertice con il genitore armato: il disegno prevede due collocazioni fin dall'inizio, oggi ne esiste una
Capogruppo come decisore della propria versionein implementazionele politiche — nascita, ritiro, ribilanciamento, ricambio — sono operative sul pool; resta da separarle per gruppo
Mappa grossa e risoluzione a due tappein implementazionela mappa fine utente → processo è operativa; l'indirizzo tipizzato è il passo che la affianca
Attuatore per clusterin implementazionematerializzazione dei pod via API, con bilanciatore, autoscaling e rilascio graduale nativi deliberatamente non usati
Pannello dei domini e matrice gruppi × dominiin implementazioneil pannello del pool è operativo e il sub-commander espone lo stesso; la vista di sistema arriva con i canali di specie mista
Metriche di sistema in formato Prometheusin implementazioneterzo livello: capacità per dominio, distribuzione fra gruppi, budget · stesso formato dei livelli sottostanti
Budget per gruppoin implementazionel'arbitraggio del ferro condiviso fra sezioni autonome

Ultimo aggiornamento della roadmap: 13 agosto 2026. Le voci del corpo del documento non cambiano quando una riga di questa tabella passa a «operativo».

I documenti precedenti

Il primo descrive il server: routing agnostico dal trasporto, grammatiche di configurazione, OpenAPI e MCP, autenticazione, sessioni, task, storage. Il secondo spiega perché lo stato di lavoro vive in memoria, perché questo lega una persona al suo processo, e come i gruppi permettono di far convivere due versioni. Questo terzo porta lo stesso disegno oltre il confine della macchina.