Torna al blog Connettività

Backpressure negli SMS A2P: come progettare code che proteggono la consegna da picchi, limiti e degradazioni

Una guida operativa per separare l'accettazione dell'invio di SMS A2P, limitare la pressione per destinazione e instradamento e gestire attese, scadenze e ritenti senza aggravare un incidente.

Diagramma operativo di una coda SMS A2P con controllo di ammissione, limiti e priorità

Cosa significa backpressure negli SMS A2P

Il backpressure negli SMS A2P è l'insieme di controlli che impedisce all'ingresso delle richieste di superare in modo sostenuto la reale capacità di elaborazione e invio. Il suo obiettivo non è accettare il maggior numero possibile di richieste, ma preservare un comportamento utile del traffico in presenza di picchi, limiti di velocità, congestione o degradazione di un instradamento.

Una risposta positiva di un'API non dimostra che il messaggio sia arrivato al terminale. In SMPP, submit_sm presenta un messaggio al Message Center per la consegna successiva; la richiesta di una ricevuta di consegna viene configurata separatamente tramite registered_delivery. Analogamente, una piattaforma può accettare e accodare un messaggio prima di inviarlo a un operatore upstream.

Se il sistema accetta più lavoro di quanto riesca a smaltire, aumentano la profondità e l'età della coda. Per il traffico con una scadenza, il risultato può essere peggiore di un rifiuto esplicito: un OTP può essere inviato troppo tardi, un avviso transazionale può perdere utilità e i ritenti possono moltiplicare i messaggi o aggravare la saturazione.

  • Considerate l'accettazione come uno stato di ammissione, non come prova di consegna.
  • Misurate la capacità di uscita effettiva per l'ambito pertinente, non solo la capacità di ingresso dell'API.
  • Applicate pressione a monte prima che il lavoro accumulato superi la finestra di utilità del messaggio.
  • Mantenete separati gli stati interni della coda dagli stati notificati dalla rete o dall'operatore.
Cosa significa backpressure negli SMS A2P

Separate ammissione, coda, pianificazione e conferma di stato

Un'architettura gestibile divide il ciclo di vita in livelli con responsabilità distinte. Questa separazione consente di decidere dove applicare i limiti ed evita che un problema di consegna venga nascosto dietro un'API apparentemente sana.

Il livello di ammissione convalida la richiesta, verifica la sua chiave di idempotenza, applica quote e decide se accettarla, differirla o rifiutarla. La coda conserva il lavoro ammesso con metadati sufficienti per definirne la priorità, far scadere i messaggi ed evitare duplicati. Il pianificatore sceglie quale messaggio può uscire in base alla capacità disponibile. Il livello di stato registra sia le transizioni interne sia le risposte e i DLR successivi.

Non è opportuno utilizzare i DLR come segnale principale di controllo in tempo reale. Gli eventi generati dagli operatori possono arrivare molto tempo dopo l'invio; pertanto, la salute immediata deve basarsi soprattutto su segnali di ammissione, coda, sessione e inoltro.

  • Ammissione: autenticazione, convalida, classificazione, deduplicazione e decisione di accettare o rifiutare.
  • Coda: persistenza, priorità, momento di creazione, finestra di utilità, destinazione, instradamento previsto e identificatore idempotente.
  • Pianificazione: selezione dei messaggi soggetta a limiti gerarchici e capacità osservata.
  • Conferma: registrazione di accettazione, accodamento, tentativo di uscita, risposta tecnica, scadenza e DLR quando presente.
Separate ammissione, coda, pianificazione e conferma di stato

Rilevate la pressione prima che la coda diventi un incidente

L'indicatore più evidente è una coda in crescita, ma non è sufficiente. Una coda può rimanere stabile e risultare comunque inaccettabile se i messaggi invecchiano troppo, se una destinazione consuma gran parte della capacità o se i ritenti spostano il traffico nuovo.

Definite soglie per classe di traffico e per ambito di controllo. La soglia utile per gli OTP non deve necessariamente valere per un avviso transazionale non urgente, e un problema limitato a una destinazione o a un instradamento non dovrebbe imporre l'arresto di tutto il traffico.

Anche la latenza di accettazione merita monitoraggio. Se l'API inizia a rallentare, potrebbe accumulare lavoro prima di rispondere o dipendere da componenti già degradati. È preferibile un'ammissione esplicita e delimitata a tempi di risposta crescenti e imprevedibili.

  • Profondità della coda totale e per account, applicazione, destinazione, instradamento, sessione e classe di traffico.
  • Età massima e percentili dell'età dei messaggi non ancora inviati.
  • Tasso di ammissione rispetto al tasso di inoltro effettivo.
  • Rifiuti temporanei, errori di sessione, tempi di risposta e riconnessioni SMPP.
  • Numero di messaggi che scadono internamente, vengono soppressi o rifiutati per policy.
  • Percentuale di capacità consumata dai ritenti rispetto ai primi tentativi.

Classificate il traffico prima di accodarlo

La priorità deve essere assegnata prima che il messaggio entri in una coda condivisa. Non basta etichettare tutto come transazionale: alcuni messaggi hanno una scadenza rigorosa, altri perdono utilità gradualmente e altri ancora possono attendere o non essere inviati durante una degradazione.

Una classificazione pratica distingue OTP, transazionale con scadenza, marketing basato sul consenso e traffico non prioritario. AWS distingue i messaggi transazionali, critici o sensibili al tempo da quelli promozionali, che non lo sono. Questa distinzione è utile come punto di partenza, ma ogni organizzazione deve documentare le proprie priorità legittime, obblighi e scadenze.

La classificazione non deve trasformarsi in un meccanismo per eludere regole di instradamento, consenso o mittente. La priorità è una decisione operativa interna per utilizzare capacità limitata in modo coerente con la finalità legittima del messaggio.

  • OTP: messaggi monouso con utilità breve; devono avere un budget di attesa ridotto e una scadenza rigorosa.
  • Transazionale con scadenza: avvisi, cambiamenti di stato o notifiche operative che perdono valore dopo un intervallo definito.
  • Marketing basato sul consenso: traffico che normalmente deve poter essere differito, limitato o sospeso senza compromettere un'operazione critica.
  • Non prioritario: traffico a bassa urgenza che deve essere il primo a essere ridotto o rifiutato sotto pressione.

Definite budget di attesa e scadenze senza confondere gli stati

Ogni classe di messaggio necessita di un budget di attesa: il tempo massimo in cui può rimanere all'interno della piattaforma prima che non abbia più senso tentare l'invio. Questo budget deve essere inferiore o uguale alla finestra di utilità aziendale e deve essere verificato rispetto alla capacità di uscita disponibile.

La scadenza interna è una decisione del sistema: per esempio, sopprimere un OTP che ha atteso oltre il limite consentito prima di assegnargli un instradamento. Non deve essere comunicata come un DLR dell'operatore. Mantenete uno stato esplicito come “scaduto internamente” o equivalente e conservate la causa della decisione.

Quando si utilizza SMPP, validity_period esprime il momento di scadenza nell'SMSC oltre il quale il messaggio deve essere scartato se non è stato consegnato. Questo periodo di validità è distinto dall'attesa precedente nella vostra coda e anche da una conferma di consegna al terminale. Nei servizi di messaggistica, il TTL controlla per quanto tempo si tenta di consegnare un SMS, non garantisce la ricezione di un DLR finale.

  • Memorizzate per messaggio: momento di creazione, scadenza interna, periodo di validità richiesto e motivo della scadenza, se si verifica.
  • Non pianificate l'uscita di messaggi il cui budget interno sia già esaurito.
  • Esponete separatamente: scaduto prima dell'invio, scaduto durante il tentativo di consegna e DLR ricevuto, quando applicabile.
  • Non interpretate una scadenza né uno stato di accettazione come conferma di ricezione sul terminale.

Applicate limiti gerarchici e controllate le raffiche

La capacità non è un singolo valore. Un sistema può disporre di capacità aggregata sufficiente ed essere comunque limitato per un account, un'applicazione, una destinazione, un instradamento, una sessione SMPP o un fornitore. I limiti devono potersi comporre: un messaggio esce solo se dispone di budget in tutti gli ambiti pertinenti.

Un modello token bucket è utile per applicare un tasso sostenuto e limitare la raffica dopo un accumulo. Il tasso limita l'inoltro continuo; la dimensione della raffica limita la velocità con cui una coda accumulata può svuotarsi. Ciò evita che il ripristino dopo una breve interruzione provochi una nuova congestione.

Applicate lo stesso limite di inoltro ai primi tentativi e ai ritenti. Se i ritenti sfuggono al controllo, consumano capacità che dovrebbe essere riservata al traffico nuovo o prioritario.

  • Limite per account, campagna o applicazione per proteggere quote e isolamento tra clienti.
  • Limite per destinazione per evitare che una numerazione, rete o Paese assorba capacità condivisa.
  • Limite per instradamento e fornitore per rispettare la capacità o la restrizione applicabile.
  • Limite per sessione SMPP per non sovraccaricare una connessione o la sua finestra operativa.
  • Riserva o ponderazione per classe di traffico per proteggere gli OTP e altri flussi con scadenza.
  • Controllo della raffica per ripristinare gradualmente il servizio dopo una pausa o degradazione.

Scegliete una strategia di ammissione esplicita

Quando la capacità non è sufficiente, esistono quattro esiti legittimi: accettare, differire, rifiutare o chiedere al mittente di ridurre il ritmo. La scelta deve dipendere dalla finestra di utilità, dalla priorità documentata, dalla possibilità di ritentare in sicurezza e dal fatto che la carenza di capacità sia globale o localizzata.

Accettare significa far entrare il messaggio nella coda entro un budget di attesa realistico. Differire significa conservarlo per una finestra successiva solo se manterrà ancora utilità. Rifiutare è appropriato quando non esiste una ragionevole possibilità di rispettare la scadenza o quando la policy non consente di accumulare altro lavoro. Richiedere una riduzione del ritmo è particolarmente utile per integrazioni in grado di adattare la propria produzione.

In HTTP, un sovraccarico temporaneo può essere comunicato con 503 e Retry-After. È preferibile che il cliente riceva un segnale esplicito e azionabile piuttosto che accettare indefinitamente richieste che probabilmente scadranno. Per rendere sicura questa integrazione, documentate chiaramente la semantica dei ritenti e le chiavi di idempotenza.

  • Accettate solo se la coda e la capacità suggeriscono che il messaggio possa uscire entro il suo budget.
  • Differite il traffico tollerante all'attesa, con una scadenza che impedisca l'invio tardivo.
  • Rifiutate OTP o messaggi la cui scadenza sia esaurita o irrealizzabile, con una causa leggibile dalla macchina e dalle operazioni.
  • Restituite un'indicazione di riduzione temporanea del ritmo quando l'interfaccia lo consente.
  • Non trasformate un rifiuto di ammissione in un'accettazione silenziosa che termina in una coda senza limiti.

Pianificate la coda con equità e priorità documentate

La pianificazione deve impedire che un singolo cliente, campagna o destinazione consumi tutta la capacità disponibile. Al tempo stesso, non deve modificare in modo opaco le priorità aziendali legittime, come la protezione degli OTP rispetto al marketing basato sul consenso durante una restrizione.

Una combinazione ragionevole consiste nell'utilizzare code per classe di traffico e applicare limiti per tenant, destinazione e instradamento prima di selezionare il messaggio successivo. All'interno della stessa classe, una policy di ripartizione equa può impedire che una fonte molto attiva monopolizzi l'inoltro.

L'ordine rigoroso di arrivo non è sempre l'ordine corretto. In presenza di scadenze, può essere preferibile dare priorità ai messaggi prossimi alla scadenza all'interno di una classe, purché la policy eviti l'inedia degli altri messaggi. Qualsiasi eccezione deve essere esplicita, verificabile e coerente con la finalità del traffico.

  • Evitate un'unica coda globale senza metadati di priorità, destinazione e scadenza.
  • Isolate destinazioni o instradamenti degradati affinché non blocchino il traffico sano.
  • Utilizzate quote o ripartizione equa all'interno di categorie equivalenti.
  • Proteggete le priorità documentate senza etichettare impropriamente traffico non urgente come critico.
  • Verificate periodicamente se vi sono messaggi che non ricevono mai un turno di inoltro.
FAQ

Domande frequenti

Accettare un SMS tramite API significa che è già stato consegnato?

No. L'accettazione indica che la richiesta è stata ammessa o accodata. In SMPP, submit_sm presenta il messaggio per la consegna successiva. La consegna e le ricevute di consegna sono fasi separate e un DLR, quando ricevuto, non deve essere confuso con una garanzia universale e immediata.

Quando è opportuno rifiutare un OTP invece di accodarlo?

È opportuno rifiutarlo esplicitamente quando la capacità disponibile e l'età della coda indicano che non potrà uscire entro la sua finestra di utilità. Inviare un OTP in ritardo può essere meno utile che informare il mittente affinché applichi il proprio flusso di recupero o generi un nuovo codice.

I ritenti devono avere un limite di velocità separato?

Devono essere soggetti allo stesso controllo di inoltro dei primi tentativi e, inoltre, avere limiti sul numero di tentativi e sul tempo. Se esclusi dal limite, possono consumare la capacità disponibile e prolungare una congestione.

Un validity_period SMPP sostituisce una scadenza interna?

No. validity_period definisce la scadenza nell'SMSC oltre la quale il messaggio deve essere scartato se non è stato consegnato. La piattaforma necessita comunque di un budget di attesa interno per impedire che messaggi ormai inutili arrivino tardi all'SMSC.

I DLR devono essere usati per rilevare una degradazione in tempo reale?

Non come unico segnale. Gli eventi provenienti dagli operatori possono arrivare con un ritardo considerevole. Per il controllo operativo immediato, monitorate ammissione, profondità ed età della coda, inoltro, errori tecnici, salute delle sessioni e comportamento per destinazione o instradamento.

Come si evitano i duplicati quando il cliente ritenta una richiesta HTTP?

Utilizzate una chiave di idempotenza persistente o un meccanismo equivalente che consenta di riconoscere una richiesta già applicata. I ritenti automatici di operazioni non idempotenti sono insicuri se il mittente non può sapere se la richiesta originale è stata elaborata.

Fonti consultate

  1. SMPP Protocol Specification v3.4, Issue 1.2SMPP Developers Forum
  2. RFC 9110: HTTP SemanticsIETF
  3. Cloud Tasks: Configure queue routing, limits, and retriesGoogle Cloud
  4. Cloud Tasks v2 API reference: RateLimitsGoogle Cloud
  5. AWS End User Messaging SMS: How SMS worksAmazon Web Services
  6. AWS End User Messaging SMS: Event types for SMS, MMS, and voiceAmazon Web Services
  7. AWS End User Messaging SMS: Example of sending an SMS or voice messageAmazon Web Services
  8. Messages resourceTwilio
  9. Outbound Message Status in Status CallbacksTwilio
  10. 30036: Validity Period ExpiredTwilio
  11. 30001: Queue overflowTwilio