Una coda di job consente di eseguire attività al di fuori del flusso immediato di una richiesta: inviare notifiche, elaborare file o sincronizzare dati. Ma quando arrivano più job di quanti i consumer riescano a completarne, si forma un backlog. Il ritardo può manifestarsi con conferme tardive, dati non aggiornati o attività che non terminano mai, con conseguenze sia per gli utenti sia per i team che gestiscono l'applicazione.
Per decidere come intervenire, non basta guardare quanti messaggi sono in attesa. Contano la loro anzianità, la velocità con cui arrivano e vengono completati, il tipo di lavoro e lo stato delle dipendenze. Aggiungere consumer può essere utile se manca capacità, ma può anche moltiplicare le query a un database già saturo. La risposta sicura parte dalla misurazione e dal riconoscimento del pattern.
Cosa rivela il backlog e quali metriche mancano

Il numero di job in attesa è un'istantanea, non una spiegazione. Può aumentare durante un picco e ridursi in seguito senza interventi, oppure rimanere stabile mentre il job più vecchio continua ad accumulare ritardo. Perciò, quando valuti come controllare il backlog di una coda PHP, è utile osservare congiuntamente:
- Tasso di ingresso: job accettati per unità di tempo.
- Tasso di uscita: job completati per unità di tempo, distinguendo quelli completati dai tentativi non riusciti.
- Anzianità: da quanto tempo è in attesa il job più vecchio, oltre ai percentili dei tempi di attesa, se disponibili.
- Durata dell'elaborazione: quanto tempo richiede ciascun tipo di job e come cambia tale durata.
- Errori e tentativi: percentuale di errori, numero di tentativi e presenza di job inviati a una coda degli errori o di quarantena.
- Stato dei consumer e delle dipendenze: processi attivi, riavvii, uso di CPU e memoria, connessioni al database e latenza dei servizi esterni.
Il tasso di uscita deve rappresentare lavoro utile completato: contare ogni tentativo come un job smaltito può nascondere un ciclo di errori e tentativi ripetuti. È inoltre importante segmentare per coda o classe di attività. Una media complessiva può mascherare il fatto che un tipo di job stia bloccando gli altri.
Diagnostica il pattern prima di modificare la capacità
Confronta le metriche su una finestra temporale adeguata all'operatività e con il comportamento abituale del sistema. I pattern orientano l'indagine, ma da soli non dimostrano la causa.
- Il tasso di ingresso supera costantemente quello di uscita: potrebbe mancare capacità, essere aumentato il volume o essersi allungata la durata dei job. Verifica le modifiche recenti, la composizione del traffico e i tempi per tipo di attività.
- Consumer attivi, ma tasso di uscita quasi nullo: cerca processi bloccati, attese indefinite, deadlock, esaurimento del pool di connessioni o chiamate esterne senza limiti di tempo. Esamina i log e le trace correlate tramite l'identificativo del job.
- Aumento della durata e della latenza delle dipendenze: i consumer potrebbero essere in attesa del database, di un'API o dello storage. Più processi possono aumentare la contesa e peggiorare la latenza.
- Errori ripetuti sugli stessi job: potrebbe trattarsi di dati non validi, di una condizione non recuperabile o di un difetto. Controlla la policy di retry: riprovare troppo presto può generare una tempesta di carico.
- Una coda cresce mentre le altre avanzano: verifica le priorità, la distribuzione dei consumer e se una classe di attività monopolizza le risorse.
Verifica anche le modifiche recenti alla configurazione e i deployment. Accertati che la telemetria distingua un consumer occupato da uno attivo ma che non fa progressi: controllare che il processo sia attivo non garantisce che i job vengano completati.
Stima la capacità di smaltimento sulla base dei dati osservati
Se il tasso di uscita sostenuto supera quello di ingresso, la coda può ridursi finché questa differenza si mantiene. Come approssimazione operativa, il tempo necessario per elaborare il backlog dipende dal numero di job in attesa diviso per la capacità netta di smaltimento: il tasso di uscita meno quello di ingresso nello stesso periodo. Se questa differenza è zero o negativa, aumentare il tempo di attesa non risolverà l'accumulo.
La stima è indicativa, non una promessa sull'ora del ripristino. Presuppone che il ritmo resti costante e che la composizione e il costo dei job siano simili. Pochi job di lunga durata, i retry o i limiti di una dipendenza possono cambiare il risultato. Usa i tassi osservati sotto carico reale e aggiorna la stima dopo ogni intervento. Per attività con costi diversi, calcola i valori per classe di job oppure misura il tempo di servizio, non soltanto il numero di messaggi.
Intervieni in sequenza e con limiti definiti
Dai priorità a misure reversibili e circoscritte. Prima di modificare il numero di consumer, concorda quale impatto può tollerare ciascuna dipendenza e come annullare la modifica.
- Limita i nuovi ingressi, se possibile: sospendi i producer non essenziali, applica dei limiti o rinvia le attività a bassa priorità. Evita di scartare job senza una regola di business, una registrazione e un meccanismo di recupero.
- Isola i job problematici: limita i tentativi, applica un'attesa progressiva quando opportuno e indirizza gli errori persistenti a una coda degli errori che possa essere esaminata. Non ignorare questi job: potrebbero richiedere una correzione e una nuova elaborazione.
- Proteggi le priorità: separa le attività urgenti da quelle di manutenzione o di elaborazione massiva e verifica che le priorità non condannino le code meno urgenti ad attese indefinite.
- Regola gradualmente la concorrenza: modifica il numero di consumer a piccoli incrementi e osserva le prestazioni e la saturazione. Mantieni limiti compatibili con le connessioni disponibili, la CPU, la memoria e le quote dei servizi esterni.
- Correggi la causa: se ci sono query lente, blocchi o chiamate senza timeout, risolvi il collo di bottiglia prima di mantenere più processi in esecuzione parallela.
L'idempotenza è particolarmente importante quando un job può essere eseguito più di una volta. Progetta gli effetti esterni e le scritture in modo che tollerino i retry, oppure integra meccanismi di deduplicazione adeguati. Verifica anche cosa accade se il consumer si arresta dopo aver prodotto l'effetto, ma prima di confermare il messaggio.
Definisci soglie e una procedura di ripristino
Definisci le soglie in base ai requisiti del servizio, non a un valore universale. Un alert può combinare l'anzianità massima o il percentile dei tempi di attesa, l'andamento del backlog, la differenza tra ingresso e uscita e il tasso di errori. L'anzianità è spesso più direttamente correlata all'impatto sugli utenti rispetto a un conteggio isolato; il volume aiuta a dimensionare l'entità del problema.
Documenta chi interviene, quali code può sospendere, quali dipendenze deve consultare e quali modifiche richiedono un'approvazione. Durante l'incidente, registra l'ora, l'ipotesi, l'azione e l'effetto osservato. Dopo ogni modifica, verifica che il tasso di uscita aumenti senza che la latenza del database, gli errori esterni, l'uso delle risorse o gli errori dell'applicazione crescano in misura inaccettabile.
Considera confermato il ripristino quando l'anzianità e il volume diminuiscono in modo costante, i job vengono completati correttamente e le dipendenze tornano a un livello stabile. Non dichiarare risolto il problema solo perché il contatore diminuisce: i messaggi potrebbero essere stati scartati o accumulati in un'altra coda.
Checklist per prevenire un nuovo accumulo

- Si misurano ingresso, uscita effettiva, anzianità, durata e retry per ciascuna coda?
- I job hanno limiti di tempo e una policy di retry finita e adeguata?
- Ci sono alert per la mancanza di progressi, non soltanto per il volume?
- La concorrenza massima rispetta i limiti delle dipendenze condivise?
- È possibile isolare una classe problematica senza interrompere tutta l'elaborazione?
- Esiste una procedura documentata per sospendere, riprendere e rielaborare i job in sicurezza?
- Metriche ed effetti collaterali vengono controllati dopo modifiche al codice, al carico o alla configurazione?
Una coda sana non è necessariamente una coda vuota: possono verificarsi variazioni normali. Il criterio pratico è che i job vengano completati entro il livello di servizio previsto, che gli errori siano visibili e che il sistema mantenga margine per assorbire i picchi. Misurare questo comportamento permette di intervenire prima che un accumulo si trasformi in un'interruzione per gli utenti.



