绝不要在请求处理器中遍历 100 万用户——而应通过队列进行扇出(fan out),将速率限制到每个 provider 能接受的水平,让每次发送都幂等(idempotent),并把失败路由到 DLQ 以便重试。API 调用只负责入队;由 worker 完成缓慢的 I/O。
架构
text
Admin ─▶ Campaign API ─▶ [enqueue job] ─▶ Kafka/SQS ─┐
▼
┌──────────────── Worker pool (autoscaled) ───────────────┐
│ claim ─▶ dedup(Redis SETNX) ─▶ rate-limiter ─▶ provider │
└──────────┬──────────────────────────────┬───────────────┘
│ ok │ fail (5xx/timeout)
▼ ▼
sent_log (DB) Retry (backoff) ─▶ DLQ
