通知系统设计
通知系统是用户产品的粘合剂——任何需要告知用户的事件(新消息、订单状态、促销活动、系统公告)都依赖它。在亿级用户规模下,通知系统的核心挑战是:如何将正确的消息以合适的渠道在恰当的时机送达目标用户。
一、通知渠道
| 渠道 | 适用场景 | 延迟 | 成本 |
|---|---|---|---|
| Push 推送 (APNs/FCM) | App 在后台时触达用户 | 秒级 | 免费 |
| 短信 | 验证码、重要通知 | 秒级 | 0.03-0.05元/条 |
| 邮件 | 营销活动、周报、账单 | 分钟级 | 极低 |
| 站内信 | App 内的消息盒子 | 实时 | 免费 |
| WebSocket | 在线用户的实时消息 | 毫秒级 | 免费 |
二、系统架构
1 | 业务系统 (订单/评论/关注等) |
三、优先级与频率控制
3.1 优先级分级
| 优先级 | 类型 | 通道 | 示例 |
|---|---|---|---|
| P0 紧急 | 验证码、支付确认 | 短信 + Push | 登录验证码 |
| P1 重要 | 订单状态、私信 | Push + 站内信 | “您的订单已发货” |
| P2 普通 | 评论回复、关注 | Push + 站内信 | “张三回复了你的评论” |
| P3 营销 | 活动推广、周报 | 邮件 + 站内信 | “周末特惠” |
3.2 防打扰
用户投诉通知的最大原因是”发太多了”。需要以下控制:
- 频率限制:同一用户每天最多 10 条 Push,3 条短信
- 时段限制:夜间(23:00-7:00)不推送非紧急通知
- 用户偏好:用户可在设置中关闭特定类型的通知
- 退订机制:每条营销邮件必须包含退订链接
- 节流合并:多条相似通知合并为一条(如”5 人回复了你”)
四、消息模板
通知内容不是每条都写死,而是基于模板 + 变量的方式渲染:
模板引擎渲染后:
1 | "您的订单 20240701001 已发货,预计 2024-07-05 送达" |
4.1 多渠道适配
同一模板需要适配不同渠道的长度限制:
1 | Push (50 字) → "您的订单已发货,预计 7月5日 送达" |
五、推送服务实现
5.1 Push 通道(APNs & FCM)
每个用户的设备有一个唯一的推送令牌(Device Token),服务端通过 APNs/FCM API 向该令牌推送消息:
1 | POST https://api.push.apple.com/3/device/{device_token} |
关键设计:
- 令牌更新:App 启动时上报最新 Device Token,服务端更新映射关系
- 批量推送:使用 HTTP/2 多路复用,单连接并发发送上万条推送
- 失效令牌清理:APNs 返回 410 Gone → 标记令牌失效,下次不推送
- 离线消息:用户打开 App 后拉取离线期间的通知列表
5.2 站内信(WebSocket)
在线用户直接通过 WebSocket 推送站内信;离线用户的消息存入数据库,下次在线时拉取:
1 | 消息表 (notifications): |
六、追踪与监控
6.1 送达追踪
完整的推送链路追踪:
1 | 发送 → 到达推送网关 → APNs/FCM 已接收 → 设备已展示 → 用户已点击 |
6.2 核心指标
| 指标 | 计算方式 | 健康值 |
|---|---|---|
| 送达率 | 已送达 / 已发送 | > 95% |
| 点击率 | 已点击 / 已展示 | 10-30% |
| 推送延迟 | 事件发生到推送到达的时间 | P99 < 5s |
七、容量估算
假设 1 亿用户,人均日收 5 条推送:
- 日均推送量:1亿 × 5 = 5 亿条
- 峰值 QPS(假设 10% 流量在 1 小时内):5亿 × 10% / 3600 ≈ 13,900 QPS
- Push 服务需要 10-20 台服务器支撑
八、小结
通知系统的设计本质上是”消息路由”问题——将正确的内容、以正确的渠道、在正确的时间、发送给正确的用户。核心架构决策包括:优先级分级控制、多渠道适配的模板系统、推送令牌的生命周期管理、以及送达追踪闭环。良好的通知系统应该在”触达用户”和”不打扰用户”之间找到平衡点。