Voltar ao blog Conectividade

Backpressure em SMS A2P: como conceber filas que protegem a entrega perante picos, limites e degradações

Um guia operacional para separar a aceitação do envio de SMS A2P, limitar a pressão por destino e rota e gerir esperas, expirações e tentativas de reenvio sem agravar um incidente.

Diagrama operacional de uma fila de SMS A2P com controlo de admissão, limites e prioridades

O que significa backpressure em SMS A2P

O backpressure em SMS A2P é o conjunto de controlos que impede que a entrada de pedidos exceda, de forma sustentada, a capacidade real de processamento e envio. O seu objetivo não é aceitar o maior número possível de pedidos, mas preservar o comportamento útil do tráfego quando existem picos, limites de taxa, congestionamento ou degradação de uma rota.

Uma resposta positiva de uma API não prova que a mensagem chegou ao terminal. Em SMPP, submit_sm apresenta uma mensagem ao Message Center para entrega posterior; o pedido de um recibo de entrega é configurado separadamente através de registered_delivery. De forma semelhante, uma plataforma pode aceitar e colocar uma mensagem numa fila antes de a enviar para um operador a montante.

Se o sistema aceitar mais trabalho do que consegue escoar, a profundidade e a antiguidade da fila aumentam. Para tráfego com prazo, o resultado pode ser pior do que uma rejeição explícita: um OTP pode ser enviado tarde, um aviso transacional pode perder utilidade e as tentativas de reenvio podem multiplicar mensagens ou agravar a saturação.

  • Trate a aceitação como um estado de admissão, e não como prova de entrega.
  • Meça a capacidade de saída efetiva em cada âmbito relevante, não apenas a capacidade de entrada da API.
  • Aplique pressão a montante antes de o trabalho acumulado exceder o prazo útil da mensagem.
  • Mantenha os estados internos da fila separados dos estados comunicados pela rede ou pelo operador.
O que significa backpressure em SMS A2P

Separe admissão, fila, agendamento e confirmação de estado

Um desenho operacional divide o ciclo de vida em camadas com responsabilidades distintas. Esta separação permite decidir onde aplicar limites e impede que um problema de entrega fique oculto por trás de uma API aparentemente saudável.

A camada de admissão valida o pedido, verifica a sua chave de idempotência, aplica quotas e decide se deve ser aceite, adiado ou rejeitado. A fila preserva o trabalho admitido com metadados suficientes para o priorizar, expirar mensagens e evitar duplicados. O agendador escolhe que mensagem pode ser enviada de acordo com a capacidade disponível. A camada de estado regista tanto transições internas como respostas e DLR posteriores.

Não é aconselhável usar os DLR como principal sinal de controlo em tempo real. Os eventos gerados pelos operadores podem chegar muito depois do envio; por isso, a saúde imediata deve basear-se sobretudo em sinais de admissão, fila, sessão e despacho.

  • Admissão: autenticação, validação, classificação, desduplicação e decisão de aceitar ou rejeitar.
  • Fila: persistência, prioridade, momento de criação, prazo útil, destino, rota prevista e identificador idempotente.
  • Agendamento: seleção de mensagens sujeita a limites hierárquicos e capacidade observada.
  • Confirmação: registo de aceitação, colocação em fila, tentativa de saída, resposta técnica, expiração e DLR quando existir.
Separe admissão, fila, agendamento e confirmação de estado

Detete a pressão antes de a fila se tornar num incidente

O indicador mais evidente é uma fila em crescimento, mas não é suficiente. Uma fila pode manter-se estável e ainda assim ser inaceitável se as mensagens envelhecerem demasiado, se um destino consumir a maior parte da capacidade ou se as tentativas de reenvio deslocarem o tráfego novo.

Defina limiares por classe de tráfego e por âmbito de controlo. O limiar adequado para OTP não tem de ser válido para um aviso transacional não urgente, e um problema limitado a um destino ou rota não deve obrigar à interrupção de todo o tráfego.

A latência de aceitação também merece acompanhamento. Se a API começar a demorar mais tempo, poderá estar a acumular trabalho antes de responder ou a depender de componentes que já estão degradados. É preferível uma admissão explícita e limitada a tempos de resposta crescentes e imprevisíveis.

  • Profundidade total da fila e por conta, aplicação, destino, rota, sessão e classe de tráfego.
  • Antiguidade máxima e percentis de antiguidade das mensagens ainda não enviadas.
  • Taxa de admissão face à taxa de despacho efetivo.
  • Rejeições temporárias, erros de sessão, tempos de resposta e reconexões SMPP.
  • Quantidade de mensagens que expiram internamente, são suprimidas ou rejeitadas por política.
  • Percentagem da capacidade consumida por tentativas de reenvio face a primeiras tentativas.

Classifique o tráfego antes de o colocar em fila

A prioridade deve ser atribuída antes de a mensagem entrar numa fila partilhada. Não basta classificar tudo como transacional: existem mensagens com prazo estrito, outras com utilidade decrescente e outras que podem esperar ou não ser enviadas durante uma degradação.

Uma classificação prática distingue OTP, transacional com prazo, marketing com consentimento e tráfego não prioritário. A AWS diferencia mensagens transacionais, críticas ou sensíveis ao tempo das promocionais, que não o são. Esta distinção é útil como ponto de partida, mas cada organização deve documentar as suas próprias prioridades legítimas, obrigações e prazos.

A classificação não deve transformar-se num mecanismo para contornar regras de rota, consentimento ou remetente. A prioridade é uma decisão operacional interna para utilizar capacidade limitada de forma coerente com a finalidade legítima da mensagem.

  • OTP: mensagens de utilização única com utilidade breve; devem ter um orçamento de espera curto e expiração estrita.
  • Transacional com prazo: alertas, alterações de estado ou avisos operacionais que perdem valor após um período definido.
  • Marketing com consentimento: tráfego que normalmente deve poder ser adiado, limitado ou pausado sem comprometer uma operação crítica.
  • Não prioritário: tráfego de baixa urgência que deve ser o primeiro a ser reduzido ou rejeitado sob pressão.

Defina orçamentos de espera e expiração sem confundir estados

Cada classe de mensagem necessita de um orçamento de espera: o tempo máximo que pode permanecer na própria plataforma antes de deixar de fazer sentido tentar enviá-la. Esse orçamento deve ser inferior ou igual ao prazo útil de negócio e deve ser revisto face à capacidade de saída disponível.

A expiração interna é uma decisão do seu sistema: por exemplo, suprimir um OTP que aguardou mais do que o permitido antes de lhe atribuir uma rota. Não deve ser comunicada como um DLR do operador. Mantenha um estado explícito como “expirado internamente” ou equivalente e preserve a causa da decisão.

Quando se utiliza SMPP, validity_period expressa o momento de expiração no SMSC, após o qual a mensagem deve ser descartada se não tiver sido entregue. Este período de validade é diferente da espera prévia na sua própria fila e também diferente de uma confirmação de entrega no terminal. Nos serviços de mensagens, o TTL controla durante quanto tempo se tenta entregar um SMS, não uma garantia de que será recebido um DLR final.

  • Guarde por mensagem: momento de criação, prazo interno, período de validade pedido e motivo de expiração, se ocorrer.
  • Não agende o envio de mensagens cujo orçamento interno já se esgotou.
  • Apresente separadamente: expirado antes do envio, expirado durante a tentativa de entrega e DLR recebido, quando aplicável.
  • Não interprete uma expiração nem um estado de aceitação como confirmação de receção no terminal.

Aplique limites hierárquicos e controle os picos súbitos

A capacidade não é um número único. Um sistema pode ter capacidade agregada suficiente e, ainda assim, estar limitado para uma conta, uma aplicação, um destino, uma rota, uma sessão SMPP ou um fornecedor. Os limites devem poder ser compostos: uma mensagem só é enviada se dispuser de orçamento em todos os âmbitos aplicáveis.

Um modelo de token bucket é útil para aplicar uma taxa sustentada e limitar o pico súbito após uma acumulação. A taxa limita o despacho contínuo; o tamanho do pico limita a velocidade a que uma fila acumulada pode ser esvaziada. Isto impede que a recuperação após uma interrupção breve cause novo congestionamento.

Aplique o mesmo limite de despacho a primeiras tentativas e a tentativas de reenvio. Se as tentativas de reenvio ficarem fora de controlo, consomem capacidade que deveria ser reservada para tráfego novo ou prioritário.

  • Limite por conta, campanha ou aplicação para proteger quotas e isolamento entre clientes.
  • Limite por destino para impedir que uma numeração, rede ou país absorva capacidade partilhada.
  • Limite por rota e fornecedor para respeitar a capacidade ou restrição aplicável.
  • Limite por sessão SMPP para não sobrecarregar uma ligação ou a sua janela operacional.
  • Reserva ou ponderação por classe de tráfego para proteger OTP e outros fluxos com prazo.
  • Controlo de picos súbitos para recuperar gradualmente após uma pausa ou degradação.

Escolha uma estratégia de admissão explícita

Quando não existe capacidade suficiente, há quatro resultados legítimos: aceitar, adiar, rejeitar ou pedir ao remetente que reduza o seu ritmo. A escolha deve depender do prazo útil, da prioridade documentada, da possibilidade de reenvio seguro e de a falta de capacidade ser global ou localizada.

Aceitar significa que a mensagem entra na fila dentro de um orçamento de espera realista. Adiar significa preservá-la para uma janela posterior apenas se ainda tiver utilidade. Rejeitar é apropriado quando não há possibilidade razoável de cumprir o prazo ou quando a política não permite acumular mais trabalho. Pedir a redução do ritmo é especialmente útil para integrações que conseguem adaptar a sua produção.

Em HTTP, uma sobrecarga temporária pode ser comunicada com 503 e Retry-After. É preferível que o cliente receba um sinal explícito e acionável do que aceitar indefinidamente pedidos que provavelmente expirarão. Para tornar essa integração segura, documente claramente a semântica de reenvio e as chaves de idempotência.

  • Aceite apenas se a fila e a capacidade indicarem que a mensagem pode sair dentro do seu orçamento.
  • Adie tráfego tolerante à espera, com uma data-limite que impeça o seu envio tardio.
  • Rejeite OTP ou mensagens cujo prazo esteja esgotado ou seja inviável, com uma causa legível por máquina e pela operação.
  • Devolva uma indicação de redução temporária do ritmo quando a interface o permitir.
  • Não transforme uma rejeição de admissão numa aceitação silenciosa que termina numa fila sem limite.

Agende a fila com equidade e prioridades documentadas

O agendamento deve impedir que um único cliente, campanha ou destino consuma toda a capacidade disponível. Ao mesmo tempo, não deve alterar de forma opaca prioridades legítimas de negócio, como proteger OTP face a marketing com consentimento durante uma restrição.

Uma combinação razoável é utilizar filas por classe de tráfego e aplicar limites por inquilino, destino e rota antes de selecionar a mensagem seguinte. Dentro da mesma classe, uma política de repartição justa pode impedir que uma fonte muito ativa monopolize o despacho.

A ordem estrita de chegada nem sempre é a ordem correta. Na presença de prazos, pode ser preferível dar prioridade a mensagens próximas da expiração dentro de uma classe, desde que a política evite a inanição das restantes mensagens. Qualquer exceção deve ser explícita, auditável e coerente com a finalidade do tráfego.

  • Evite uma única fila global sem metadados de prioridade, destino e prazo.
  • Isole destinos ou rotas degradados para que não bloqueiem tráfego saudável.
  • Utilize quotas ou repartição justa dentro de categorias equivalentes.
  • Proteja prioridades documentadas sem classificar indevidamente tráfego não urgente como crítico.
  • Reveja periodicamente se existem mensagens que nunca recebem oportunidade de despacho.
FAQ

Perguntas frequentes

Aceitar um SMS por API significa que já foi entregue?

Não. A aceitação indica que o pedido foi admitido ou colocado em fila. Em SMPP, submit_sm apresenta a mensagem para entrega posterior. A entrega e os recibos de entrega são etapas separadas, e um DLR, quando é recebido, também não deve ser confundido com uma garantia universal e imediata.

Quando é aconselhável rejeitar um OTP em vez de o colocar em fila?

É aconselhável rejeitá-lo explicitamente quando a capacidade disponível e a antiguidade da fila indicam que não poderá ser enviado dentro do seu prazo útil. Enviar um OTP tarde pode ser menos útil do que informar o remetente para que aplique o seu fluxo de recuperação ou gere um novo código.

As tentativas de reenvio devem ter um limite de taxa separado?

Devem estar sujeitas ao mesmo controlo de despacho que as primeiras tentativas e, além disso, ter limites de número de tentativas e de tempo. Se forem excluídas do limite, podem consumir a capacidade disponível e prolongar um congestionamento.

Um validity_period de SMPP substitui uma expiração interna?

Não. validity_period define a expiração no SMSC, após a qual a mensagem deve ser descartada se não tiver sido entregue. A plataforma continua a necessitar de um orçamento de espera interno para impedir que mensagens sem utilidade cheguem tarde ao SMSC.

Devem ser usados DLR para detetar uma degradação em tempo real?

Não como sinal único. Os eventos provenientes dos operadores podem chegar com um atraso considerável. Para controlo operacional imediato, monitorize admissão, profundidade e antiguidade da fila, despacho, erros técnicos, saúde das sessões e comportamento por destino ou rota.

Como evitar duplicados quando o cliente tenta novamente um pedido HTTP?

Utilize uma chave de idempotência persistente ou um mecanismo equivalente que permita reconhecer um pedido já aplicado. As tentativas automáticas de operações não idempotentes são inseguras se o remetente não conseguir saber se o pedido original foi processado.

Fontes consultadas

  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