通知系统设计

通知系统是用户产品的粘合剂——任何需要告知用户的事件(新消息、订单状态、促销活动、系统公告)都依赖它。在亿级用户规模下,通知系统的核心挑战是:如何将正确的消息以合适的渠道在恰当的时机送达目标用户。

一、通知渠道

渠道 适用场景 延迟 成本
Push 推送 (APNs/FCM) App 在后台时触达用户 秒级 免费
短信 验证码、重要通知 秒级 0.03-0.05元/条
邮件 营销活动、周报、账单 分钟级 极低
站内信 App 内的消息盒子 实时 免费
WebSocket 在线用户的实时消息 毫秒级 免费

二、系统架构

1
2
3
4
5
6
7
8
9
10
11
业务系统 (订单/评论/关注等)

[通知网关] ← 统一入口,验证、限流、去重

[消息队列] ← Kafka,解耦业务系统和通知通道

├── [Push 服务] → APNs / FCM / 华为推送
├── [短信服务] → 阿里云/腾讯云短信网关
├── [邮件服务] → SendGrid / SES
├── [站内信服务] → WebSocket 推送 + 消息存储
└── [WebSocket 服务] → 实时推送

三、优先级与频率控制

3.1 优先级分级

优先级 类型 通道 示例
P0 紧急 验证码、支付确认 短信 + Push 登录验证码
P1 重要 订单状态、私信 Push + 站内信 “您的订单已发货”
P2 普通 评论回复、关注 Push + 站内信 “张三回复了你的评论”
P3 营销 活动推广、周报 邮件 + 站内信 “周末特惠”

3.2 防打扰

用户投诉通知的最大原因是”发太多了”。需要以下控制:

  • 频率限制:同一用户每天最多 10 条 Push,3 条短信
  • 时段限制:夜间(23:00-7:00)不推送非紧急通知
  • 用户偏好:用户可在设置中关闭特定类型的通知
  • 退订机制:每条营销邮件必须包含退订链接
  • 节流合并:多条相似通知合并为一条(如”5 人回复了你”)

四、消息模板

通知内容不是每条都写死,而是基于模板 + 变量的方式渲染:

1
2
3
4
5
模板: "订单通知"
内容: "您的订单 {{order_id}}{{status}}
预计{{delivery_date}}送达"

变量: {order_id: "20240701001", status: "发货", delivery_date: "2024-07-05"}

模板引擎渲染后:

1
"您的订单 20240701001 已发货,预计 2024-07-05 送达"

4.1 多渠道适配

同一模板需要适配不同渠道的长度限制:

1
2
3
Push (50 字) → "您的订单已发货,预计 7月5日 送达"
短信 (70 字) → "【XX商城】订单20240701001已发货,预计7月5日送达"
邮件 (无限) → 完整 HTML 格式 + 物流详情链接

五、推送服务实现

5.1 Push 通道(APNs & FCM)

每个用户的设备有一个唯一的推送令牌(Device Token),服务端通过 APNs/FCM API 向该令牌推送消息:

1
2
3
4
5
6
7
8
9
POST https://api.push.apple.com/3/device/{device_token}
Authorization: Bearer {jwt_token}
{
"aps": {
"alert": {"title": "新消息", "body": "张三发来一条消息"},
"badge": 3,
"sound": "default"
}
}

关键设计:

  • 令牌更新:App 启动时上报最新 Device Token,服务端更新映射关系
  • 批量推送:使用 HTTP/2 多路复用,单连接并发发送上万条推送
  • 失效令牌清理:APNs 返回 410 Gone → 标记令牌失效,下次不推送
  • 离线消息:用户打开 App 后拉取离线期间的通知列表

5.2 站内信(WebSocket)

在线用户直接通过 WebSocket 推送站内信;离线用户的消息存入数据库,下次在线时拉取:

1
2
3
4
5
6
7
8
消息表 (notifications):
id BIGINT PK
user_id BIGINT INDEX
type ENUM('SYSTEM','COMMENT','ORDER','PROMOTION')
title VARCHAR(200)
body TEXT
is_read BOOLEAN DEFAULT FALSE
created_at TIMESTAMP

六、追踪与监控

6.1 送达追踪

完整的推送链路追踪:

1
2
3
4
发送 → 到达推送网关 → APNs/FCM 已接收 → 设备已展示 → 用户已点击
│ │ │ │ │
[指标1] [指标2] [指标3] [指标4]
│ 发送量 送达率 展示率 点击率

6.2 核心指标

指标 计算方式 健康值
送达率 已送达 / 已发送 > 95%
点击率 已点击 / 已展示 10-30%
推送延迟 事件发生到推送到达的时间 P99 < 5s

七、容量估算

假设 1 亿用户,人均日收 5 条推送:

  • 日均推送量:1亿 × 5 = 5 亿条
  • 峰值 QPS(假设 10% 流量在 1 小时内):5亿 × 10% / 3600 ≈ 13,900 QPS
  • Push 服务需要 10-20 台服务器支撑

八、小结

通知系统的设计本质上是”消息路由”问题——将正确的内容、以正确的渠道、在正确的时间、发送给正确的用户。核心架构决策包括:优先级分级控制、多渠道适配的模板系统、推送令牌的生命周期管理、以及送达追踪闭环。良好的通知系统应该在”触达用户”和”不打扰用户”之间找到平衡点。