高 进阶
通知系统设计#
一句话答案#
通知系统核心设计:业务方发通知请求 → MQ 削峰 → 通知中心(模板渲染+去重+频控+偏好过滤)→ 多渠道分发(站内信/Push/SMS/Email),通过优先级队列 + 限流 + 重试保证可靠送达。
核心要点
整体架构#
业务方 → 通知 API → Kafka → 通知中心引擎 → 渠道网关 → 用户
│
┌───────────────┼───────────────┐
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ 站内信 │ │ Push推送 │ │ SMS/Email │
│ (自建) │ │ (APNs/FCM) │ │ (三方服务) │
└───────────┘ └───────────┘ └───────────┘plaintext核心流程#
1. 业务方调用: notify(userId, templateId, params, channels, priority)
2. 消息入 MQ(Kafka),按 priority 分 Topic
3. 通知引擎消费:
a. 模板渲染(标题/正文/跳转链接)
b. 去重检查(同一通知 X 分钟内不重发)
c. 频控检查(单用户每天最多 N 条 Push)
d. 用户偏好过滤(用户关闭了某类通知)
e. 免打扰时段检查(22:00-08:00 延迟发送)
4. 分发到各渠道网关
5. 记录发送日志 + 状态回调plaintext多渠道设计#
| 渠道 | 特点 | 送达率 | 成本 |
|---|---|---|---|
| 站内信 | 用户打开 App 才看到 | 低(需主动查看) | 免费 |
| Push | 系统通知栏 | 高(Android)/中(iOS) | 免费 |
| SMS | 100% 送达 | 极高 | ¥0.04/条 |
| 可能进垃圾箱 | 中 | 低 | |
| 企微/钉钉 | 工作场景 | 高 | 免费 |
渠道降级策略:
高优先级通知(交易/安全):Push + SMS 双发
普通通知(营销):Push → 未送达 → 站内信
低优先级(推荐):仅站内信plaintext频控与去重#
// 频控:滑动窗口限流
// key = user:{userId}:channel:{channel}:date:{date}
// Redis INCR + EXPIRE
// 去重:
// key = dedup:{userId}:{templateId}:{bizId}
// Redis SETNX + TTL(如 5 分钟内同一通知不重发)
// 免打扰:
// 22:00-08:00 的通知写入延迟队列(Redis ZSET + score=目标发送时间)java优先级队列#
高优先级(P0):验证码、安全告警、交易通知 → 独立 Topic,专用消费者
中优先级(P1):订单状态、系统通知 → 共享 Topic
低优先级(P2):营销、推荐 → 低优先级 Topic,限速消费
实现:Kafka 多 Topic + 消费者资源倾斜plaintext模板管理#
模板示例:
标题: "您的订单 {{orderNo}} 已发货"
正文: "预计 {{deliveryDate}} 送达,快递单号 {{trackingNo}}"
跳转: "app://order/detail?id={{orderId}}"
模板中心:运营后台配置,支持 A/B 测试不同文案
多语言:根据用户 locale 选择模板版本plaintext可观测性#
核心指标:
- 发送量/成功率/失败率(per channel)
- 端到端延迟(从业务调用到用户收到)
- 打开率/点击率(Push/Email 的 CTR)
- 退订率/投诉率(Email 域名信誉)plaintext面试回答(2分钟版)
通知系统的核心是「接收→处理→分发」三阶段。接收层提供统一 API 给业务方,消息入 Kafka 按优先级分 Topic 削峰。处理层是通知引擎,依次做模板渲染、去重(Redis SETNX 同一通知短时间不重发)、频控(滑动窗口限制每日推送量)、用户偏好过滤和免打扰时段检查。分发层对接多渠道网关:站内信自建、Push 走 APNs/FCM、SMS/Email 走三方。渠道降级策略是高优先级(验证码/安全)Push+SMS 双发,普通通知仅 Push,低优先级仅站内信。可靠性保证:MQ 持久化 + 消费确认 + 失败重试(指数退避)+ 渠道降级。优先级通过 Kafka 多 Topic + 消费者资源倾斜实现。免打扰用 Redis ZSET 延迟队列,到时间再消费发送。
追问与易错
追问方向:
- “怎么保证通知不丢?”→ MQ 持久化 + 消费 ACK + 失败重试 + 状态追踪
- “怎么防止用户被骚扰?”→ 频控 + 去重 + 偏好设置 + 免打扰时段
- “Push 送达率怎么提高?”→ 多通道(厂商通道/自建长连接)+ 离线转 SMS
- “百万用户群发怎么做?”→ 分批发送 + 限速 + 异步(不阻塞业务方)
易错点:
- ❌ “通知就是发个消息”——需要去重、频控、偏好、降级等完整链路
- ❌ “所有通知都 Push”——低优先级通知过多会导致用户关闭推送权限
- ❌ “SMS 作为主要渠道”——成本高,仅用于高优先级和兜底