概覽
設計一個高度可靠的通知系統,支援推播通知、SMS 和電子郵件,用於超過 100 萬用戶。該系統必須保證:
- 無重複通知
- 無遺漏發送
- 供應商故障時的優雅降級
- 可擴展性和可觀察性
高階架構
Client/API
↓
Notification Service
↓
Message Queue (Kafka/SQS/RabbitMQ)
↓
Notification Workers
↓
Provider Adapters
(SendGrid, Twilio, Firebase, etc.)
↓
Webhook/Event Processor
↓
Notification Database + Audit Logs
核心組件
1. 通知 API 服務
處理:
- 通知建立
- 驗證
- 唯一性檢查
- 排隊消息
每個請求都獲得:
- 通知識別碼
- 唯一性金鑰
服務會在處理前儲存通知,以確保持久性
2. 消息隊列
用於異步處理的 Kafka/SQS/RabbitMQ
好處:
- 解耦生產者和消費者
- 吸收流量尖峰
- 支援重試
- 防止請求阻塞
訊息會持續儲存,直到成功處理為止.
3. 通知工作員
專用工作員用於:
- 電子郵件
- 簡訊
- 推播通知
職責:
- 處理佇列訊息
- 發送通知
- 重試暫時性失敗
- 更新送貨狀態
員工水平擴展.
可靠性策略
給予性
每個通知都有:
- 獨特的通知_id
- 給予性鍵
資料庫約束:
UNIQUE(idempotency_key)
發送前:
- 工人檢查通知是否已成功
- 在重試期間防止重複發送
重試 & 失敗處理
失敗分類為:
- 暫時性 → 重試
- 永久性 → 立即失敗
重試策略:
- 指數退避
- 死信佇列 (DLQ)
- 最大重試閾值
範例:
1 min → 5 min → 15 min → 1 hour
優雅降級
如果提供者失敗:
- 備用提供者自動啟動
範例:
Twilio fails → switch to Termii
SendGrid fails → switch to SES
斷路器防止持續呼叫不健康的供應商.
送貨追蹤
Webhook 處理器接收:
- 已送達
- 送達失敗
- 退回
- 已開啟事件
所有事件儲存於審計表中.
資料庫設計
表格:
- 通知
- 送達嘗試
- 提供者日誌
- 範本
- 用戶偏好
索引:
(user_id, created_at)
(status, channel)
(notification_id)
防止錯過發送
為避免訊息丟失:
- 通知儲存於排隊前
- 使用交易發送模式
- 和解任務掃描卡住的通知
範例:
PENDING > 10 mins → requeue
觀察力
監控:
- 佇列深度
- 提供者延遲
- 重試次數
- 失敗交付率
工具:
- Prometheus
- Grafana
- CloudWatch
- Sentry
警報會在異常失敗尖峰時觸發.
可擴展性
系統支援通過以下方式支持100萬以上用戶:
- 水平工作員擴展
- 分區隊列
- 無狀態服務
- Redis快取
- 適用批次處理
安全性
- 加密提供者憑證
- 簽署的網頁回呼
- 速率限制
- RBAC供管理員存取
- 所有通知事件的審計記錄
技術堆疊範例
- 後端:Node.js / Python
- 佇列:Kafka或SQS
- 資料庫: PostgreSQL
- 快取: Redis
- 提供者: Twilio, Firebase, SendGrid
- 監控: Grafana + Prometheus
- 部署: Kubernetes/ECS











