如何避免重复发送推送消息:深入解析 cid 功能
在推送系统中,重复推送是一个常见问题,尤其是在网络不稳定或系统重试的场景下。本文将深入解析 cid(Client ID)功能,帮助您利用这一机制有效避免消息重复发送。
立即推送中的 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
处理流程
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 功能构建更健壮的推送系统,彻底解决重复推送问题。