Sistemi real-time e distribuiti
Pipeline che sotto carico si piegano invece di spezzarsi.
Costruisco backend real-time ad alto throughput in Elixir e OTP: motori di invio che spingono milioni di messaggi, sistemi di job che non perdono mai lavoro e interfacce live che si aggiornano mentre le cose accadono.
Quando “in staging funzionava” non basta
I sistemi real-time raramente cedono al carico medio. Cedono quando parte una campagna e diecimila persone rispondono nello stesso minuto, quando un’API a valle inizia a fare throttling, o quando una tempesta di retry raddoppia un traffico che già facevi fatica a reggere.
In Turn.io ho costruito il motore di invio massivo usato per campagne nazionali di salute pubblica, tra cui una che ha raggiunto 14,7 milioni di persone, e per i promemoria delle campagne vaccinali nazionali. Combina rate limiting, backpressure, tracciamento delle consegne e retry. Ho costruito anche l’infrastruttura di job e pipeline dati su Oban Pro e un sistema di trigger in stile IFTTT con un motore di regole, tutto in Elixir e Phoenix su Google Cloud e Kubernetes.
Cosa costruisco
Pipeline ad alto throughput. Stadi guidati dalla domanda (GenStage, Broadway) in cui sono i consumer a prelevare il lavoro, le code restano limitate e il throughput si assesta su quello che la dipendenza più lenta consente.
Rate limiting e retry fatti bene. Token bucket per mittente o per tenant, retry con backoff esponenziale e jitter, chiavi di idempotenza perché un retry non invii mai due volte lo stesso messaggio.
Sistemi di job affidabili. Oban per il lavoro che non si può perdere: invii programmati, webhook verso terze parti, esportazioni di dati, automazioni in stile cron, con unicità e rate limit per coda.
Motori di regole e trigger. Automazioni guidate dagli eventi (“quando succede X e Y è vero, fai Z”) che anche chi non è un ingegnere può configurare in sicurezza.
Interfacce live. Phoenix LiveView e PubSub per dashboard e inbox che si aggiornano in tempo reale senza bisogno di un team frontend separato.
Come lavoro
- Modellare il carico. Medie, picchi, raffiche e i rate limit che non controlli.
- Rendere limitata ogni coda e guidato dalla domanda ogni stadio. Decidere in anticipo cosa succede in caso di sovraccarico: rallentare, scartare o rimandare.
- Strumentare prima di ottimizzare. Eventi di telemetria su ogni stadio, così vedi dove va a finire il tempo.
- Fare load test con forme di traffico realistiche, comprese le modalità di guasto.
Servizi correlati
- Sviluppo WhatsApp Business Platform
- PostgreSQL ed Elasticsearch su larga scala: dove finiscono tutti quei messaggi.
Come possiamo collaborare
Revisione della scalabilità
Da una a due settimane di profilazione del sistema sotto carico, per trovare i veri colli di bottiglia e scrivere un piano con le priorità.
Sviluppo
Progettazione e sviluppo end-to-end di una pipeline, di un sistema di job o di una funzionalità real-time, con load test prima del lancio.
Senior engineer nel tuo team
Part-time nel tuo team per guidare un progetto di scalabilità e far crescere il team su OTP.
Domande frequenti
Perché Elixir per i sistemi real-time?
La BEAM ti dà milioni di processi leggeri e isolati, alberi di supervisione che riavviano ciò che si rompe e uno scambio di messaggi che si sposa in modo naturale con i carichi di messaggistica. Rispetto alla maggior parte dei runtime, rende molto più facile gestire bene l’ordinamento per utente, la backpressure e il degrado controllato.
Cos’è la backpressure e perché è importante?
Backpressure significa che gli stadi a valle comunicano a quelli a monte quanto lavoro possono accettare. Senza, un picco di traffico riempie memoria e code finché qualcosa non cede. Con la backpressure, il sistema rallenta in modo controllato e si riprende da solo.
Lavori anche su sistemi non scritti in Elixir?
Sì. I concetti si trasferiscono (code limitate, domanda, idempotenza, rate limiting) e scrivo anche Python e TypeScript. Detto questo, è in Elixir che rendo di più.
Fai load test?
Sì. Faccio load test prima del lancio e riproduco traffico con la stessa forma di quello di produzione, compresi picchi improvvisi, API a valle lente e retry, perché è lì che arrivano le sorprese.
Articoli correlati
Costruire un receiver di webhook affidabile per la WhatsApp Cloud API su larga scala
Webhook della WhatsApp Cloud API su larga scala: verifica della firma sul body grezzo, risposta 200 immediata, deduplica, ordine per contatto e media.
Backpressure in Elixir: inviare milioni di messaggi WhatsApp senza crollare
Progettare un motore di invio massivo WhatsApp in Elixir: pipeline Broadway guidate dalla domanda, token bucket per numero, retry con jitter e stati in batch.
Come partizionare una tabella PostgreSQL da 1 TB senza downtime: il metodo della default partition
Partiziona una tabella Postgres da 1 TB senza downtime: agganciala come DEFAULT partition, copia lo storico con job Oban e fai lo swap in una transazione breve.
Il partitioning di PostgreSQL in pratica: chiavi di partizione, pruning, index e retention
Come si comporta davvero il partitioning di PostgreSQL: scelta della chiave, pruning verificato con EXPLAIN, index, vincoli, retention e le insidie di Ecto.