如何避免重複推播通知:深入解析CID功能
在推送通知系統中,重複推送是一個常見問題,尤其是在網絡不穩定或系統重試的場景中。本文將深入解析客戶端ID(CID)功能,協助您利用此機制有效防止消息重複發送。
即時推送中的CID功能
核心功能
CID是一個可選參數,用於標識特定的推送請求。當使用相同的CID重複發起請求時:
- 系統會返回先前成功推送的
msg_id
- 避免消息重複推送到用戶
- 提供冪等性保證(相同操作多次執行效果相同)
關鍵特性
特性 | 說明 |
---|---|
有效期 | 1小時 |
格式要求 | 字母、數字、底線、連字符,長度≤64個字符 |
唯一性 | 在相同的appkey下必須唯一 |
支援場景 | 單一推送和批次推送 |
使用場景
- 網絡重試:網絡不穩定時使用相同的CID重試推送
- 冪等性保證:確保同一條消息不會被重複推送
- 請求追蹤:通過CID追蹤特定推送的狀態
請求範例
單一推送使用CID
curl --insecure -X POST -v https://pushapi-sgp.engagelab.com/v4/push \
-H "Content-Type: application/json" \
-u "AppKey:MasterSecret" \
-d '{
"options": {
"cid": "order-notify-20230701-001",
"time_to_live": 60
}
}'
curl --insecure -X POST -v https://pushapi-sgp.engagelab.com/v4/push \
-H "Content-Type: application/json" \
-u "AppKey:MasterSecret" \
-d '{
"options": {
"cid": "order-notify-20230701-001",
"time_to_live": 60
}
}'
此代碼塊在浮窗中顯示
批次推送使用CID
curl --insecure -X POST -v https://pushapi-sgp.engagelab.com/v4/push/batch/regid \
-H "Content-Type: application/json" \
-u "AppKey:MasterSecret" \
-d '{
"requests": [
{
"options": {
"cid": "user-12345-notification",
"time_to_live": 60
}
}
]
}'
curl --insecure -X POST -v https://pushapi-sgp.engagelab.com/v4/push/batch/regid \
-H "Content-Type: application/json" \
-u "AppKey:MasterSecret" \
-d '{
"requests": [
{
"options": {
"cid": "user-12345-notification",
"time_to_live": 60
}
}
]
}'
此代碼塊在浮窗中顯示
回應處理
首次推送成功
{
"msg_id": "2460001"
}
{
"msg_id": "2460001"
}
此代碼塊在浮窗中顯示
相同CID重複推送
{
"msg_id": "2460001" // 返回首次推送的msg_id
}
{
"msg_id": "2460001" // 返回首次推送的msg_id
}
此代碼塊在浮窗中顯示
CID格式錯誤
{
"error": {
"code": 23003,
"message": "CID格式不符合要求"
}
}
{
"error": {
"code": 23003,
"message": "CID格式不符合要求"
}
}
此代碼塊在浮窗中顯示
錯誤處理
錯誤碼 | 說明 | 處理方式 | HTTP狀態碼 |
---|---|---|---|
21003 | cid 格式不合法、長度超過限制 | 檢查 cid 是否符合格式要求;確保 cid 長度不超過 64 字元 | 400 |
最佳實踐
- 關鍵業務使用CID:對支付通知、重要提醒等消息使用CID
- 生成有意義的標識:使用
業務類型-用戶ID-時間戳
的格式(例如payment-12345-202307011030
) - 網絡重試機制:遇到網絡錯誤時使用相同的CID重試
- 批次推送區分標識:為批次推送中的每個請求使用獨立的CID以便追蹤
- 客戶端記錄CID:用於消息去重和狀態查詢
定時任務中的CID功能
核心功能
CID同樣適用於定時任務創建,防止重複創建相同的定時任務:
- 使用相同的CID會返回先前創建的
schedule_id
- 避免系統創建重複的定時任務
關鍵特性
特性 | 說明 |
---|---|
有效期 | 1小時 |
格式要求 | 字母、數字、底線、連字符,長度≤64個字符 |
唯一性 | 在相同的appkey下必須唯一 |
請求範例
curl --insecure -X POST -v https://pushapi-sgp.engagelab.com/v4/schedules \
-H "Content-Type: application/json" \
-u "AppKey:MasterSecret" \
-d '{
"cid": "daily-reminder-202307",
"trigger": {
"daily": {
"start": "2023-07-01",
"time": "09:00:00"
}
}
}'
curl --insecure -X POST -v https://pushapi-sgp.engagelab.com/v4/schedules \
-H "Content-Type: application/json" \
-u "AppKey:MasterSecret" \
-d '{
"cid": "daily-reminder-202307",
"trigger": {
"daily": {
"start": "2023-07-01",
"time": "09:00:00"
}
}
}'
此代碼塊在浮窗中顯示
回應處理
首次創建成功
{
"schedule_id": "0123456789"
}
{
"schedule_id": "0123456789"
}
此代碼塊在浮窗中顯示
相同CID重複創建
{
"schedule_id": "0123456789" // 返回首次創建的schedule_id
}
{
"schedule_id": "0123456789" // 返回首次創建的schedule_id
}
此代碼塊在浮窗中顯示
最佳實踐
- 週期性任務標識:在CID中包含週期信息(例如
weekly-report-2023w27
) - 任務參數摘要:包含關鍵參數的哈希值(例如
birthday-reminder-md5(params)
) - 分布式系統協調:多個服務實例使用相同的CID避免重複創建
- 任務更新機制:修改任務時使用新的CID
EngageLab處理流程
graph TD A[接收請求] --> B{包含CID?} B -->|是| C[查詢Redis] B -->|否| D[正常處理] C --> E{CID存在?} E -->|是| F[返回存儲的msg_id/schedule_id] E -->|否| G[處理請求] G --> H[存儲CID → ID映射] H --> I[返回新ID]
常見問題解答
Q:為什麼CID有效期是1小時?
A:足以覆蓋典型的重試場景,同時避免存儲無限增長。重要業務可配合自身日誌延長去重週期。
Q:不同的appkey可以使用相同的CID嗎?
A:可以。CID只需在相同的appkey下保持唯一。
Q:CID是否保證全局唯一?
A:只需在相同的appkey下保證唯一即可,系統不要求全局唯一。
Q:如何驗證CID格式?
A:使用正則表達式驗證:/^[a-zA-Z0-9_-]{1,64}$/
總結
通過合理使用CID參數,您可以:
- ✅ 避免網絡重試導致的消息重複
- ✅ 保證重要業務消息的冪等性
- ✅ 簡化分布式系統的消息追蹤
- ✅ 提高系統整體可靠性
關鍵實施建議:
- 為關鍵業務消息添加CID
- 採用
業務-實體-時間
的命名規範 - 客戶端實現基於CID的去重邏輯
- 監控CID相關錯誤代碼
通過本文指南,您可以有效利用CID功能構建更健壯的推送系統,徹底解決重複推送問題。