跳转到内容

37. Push Notification Service 推送服务

你想给自己做一个提醒工具,定时弹出浏览器通知提醒待办事项。

  • 使用浏览器Notification API发送通知
  • 用户授权通知权限
  • 定时触发通知
用纯HTML+JS实现一个浏览器通知提醒工具:
功能:
1. 请求Notification权限(用户点击按钮授权)
2. 添加提醒:输入标题、内容、时间(相对时间如"5分钟后")
3. 到时间后弹出浏览器通知
4. 提醒列表:显示所有提醒(待触发/已触发)
5. 支持重复提醒(每小时/每天)
6. 点击通知跳转回页面
7. 所有提醒存localStorage
技术:纯HTML+CSS+JavaScript, Notification API, setTimeout/setInterval
单个index.html文件
  • 授权后能收到浏览器通知
  • 定时提醒准时触发
  • 重复提醒正常工作
  • 点击通知能跳转
  • 提醒列表显示正确
  • 刷新页面后提醒不丢失(重新计算定时器)
  • Notification API使用 → Module: 浏览器API
  • 权限管理(用户授权)→ Module: Web安全
  • 定时器管理 → Module: JavaScript异步

需要从服务器向用户推送消息,比如新订单通知、系统公告。

  • 服务端主动推送消息到浏览器
  • 用户设备注册和管理
  • 推送记录持久化
用Go+Gin实现SSE推送服务:
后端:
1. SSE连接管理:
- 用户连接时注册(user_id → SSE连接)
- 断开时清理
- 心跳保活(每30秒发ping)
2. SQLite表:
- devices(id, user_id, device_type, connected_at)
- notifications(id, user_id, title, body, status, created_at, read_at)
- status: pending / sent / read
3. API:
- GET /api/notifications/stream — SSE连接端点
- POST /api/notifications/send — 发送通知(管理接口)
- GET /api/notifications — 历史通知列表
- PUT /api/notifications/:id/read — 标记已读
推送逻辑:
1. 调用send接口 → 创建notification记录
2. 查找用户SSE连接 → 推送给在线用户
3. 用户不在线 → 标记pending,下次连接时推送未读
前端:
1. EventSource连接SSE
2. 收到消息显示Toast通知
3. 通知列表页(全部/未读)
4. 未读数量角标
技术:Go+Gin, SSE(Server-Sent Events), SQLite, React
  • SSE连接建立并保持
  • 发送通知后在线用户立即收到
  • 离线用户上线后收到未读通知
  • 标记已读功能正常
  • 未读角标数字正确
  • 连接断开后自动重连
  • SSE vs WebSocket对比 → Module: 实时通信
  • 连接管理(注册/清理)→ Module: 连接池
  • 离线消息补推 → Module: 消息投递

不仅浏览器,还要支持APP推送(FCM/APNs),需要模板管理。

  • 多渠道推送(WebSocket + FCM/APNs接口预留)
  • 推送模板管理
  • 推送记录和状态跟踪
在V2基础上实现多渠道推送系统:
WebSocket升级:
1. 将SSE替换为WebSocket(双向通信)
2. 支持在线状态查询
3. 多端同时在线(同一用户多个设备)
推送渠道:
1. 渠道接口抽象:
type PushChannel interface {
Send(deviceToken string, message Message) error
}
2. 实现:WebSocketChannel(实际推送)
3. 预留:FCMChannel, APNsChannel(返回模拟成功)
4. 设备注册时记录渠道类型(web/android/ios)
5. 推送时按设备渠道分发
推送模板(PostgreSQL):
1. templates表:id, name, title_template, body_template, channel
2. 模板变量:{{.UserName}}, {{.OrderID}}等
3. Go text/template渲染
4. 创建通知时可选模板+变量,自动渲染内容
推送记录:
1. push_logs表:notification_id, channel, device_id, status, sent_at, error
2. 每次推送记录发送状态
3. API查询推送到达情况
技术:Go+Gin, PostgreSQL, WebSocket(gorilla/websocket), React
  • WebSocket连接稳定
  • 多端同时在线都能收到通知
  • 模板渲染变量替换正确
  • 推送日志完整记录
  • 渠道接口抽象正确,易于扩展
  • 按设备类型正确分发
  • 接口抽象(策略模式)→ Module: 设计模式
  • Go template模板引擎 → Module: Go标准库
  • 多端推送架构 → Module: 推送系统
  • WebSocket连接管理 → Module: 实时系统

V4 — 1000个用户:精准推送与统计

Section titled “V4 — 1000个用户:精准推送与统计”

运营需要按用户群体推送,分析推送效果(打开率、点击率)。

  • 用户分群(标签系统)
  • 定时推送调度
  • 推送效果统计
在V3基础上实现精准推送和统计:
用户标签:
1. 标签管理:创建/删除标签(如"活跃用户"、"北京"、"VIP")
2. 用户打标:手动或规则自动(如30天内登录=活跃)
3. 推送时选择标签 → 自动匹配用户列表
4. 支持标签组合(AND/OR)
定时推送:
1. 创建推送任务:内容+目标标签+发送时间
2. 调度器:定时扫描待发送任务
3. 任务状态:draft/scheduled/sending/sent/failed
4. 支持取消未发送的定时任务
5. 发送进度展示(已发送/总数)
推送统计:
1. 指标采集:
- 送达数:推送成功的设备数
- 展示数:客户端上报已展示
- 点击数:用户点击通知
2. 每条推送的统计面板:
- 送达率 = 送达数/目标数
- 点击率 = 点击数/展示数
3. Redis计数器实时统计
4. 每日汇总报表
技术:Go+Gin, PostgreSQL, Redis, 定时调度器, React
  • 标签创建和用户打标正常
  • 按标签筛选用户正确
  • 标签组合查询正确
  • 定时任务准时触发
  • 取消定时任务正常
  • 送达/展示/点击数据准确
  • 统计面板数据实时更新
  • 标签系统设计 → Module: 数据建模
  • 定时调度器实现 → Module: 任务调度
  • 漏斗分析(送达→展示→点击)→ Module: 数据分析
  • Redis计数器 → Module: 缓存应用

V5 — 1万个用户:高并发批量推送

Section titled “V5 — 1万个用户:高并发批量推送”

一次推送10万用户,不能卡死服务,要保证送达且可重试。

  • 消息队列削峰填谷
  • 分批发送策略
  • 失败重试机制
在V4基础上实现高并发推送:
消息队列:
1. 推送任务拆分:10万用户 → 每批1000人 → 100个子任务
2. 子任务写入消息队列(Redis Stream)
3. 多个worker消费子任务并发推送
4. worker数量可配置(默认5个)
分批发送:
1. 总任务 → 按批次拆分 → 入队 → worker消费 → 推送
2. 每批内串行发送(避免推送渠道限流)
3. 批次间可配置间隔(默认1秒)
4. 实时进度:已发送/总数,预估剩余时间
重试机制:
1. 推送失败 → 记录失败原因 → 放入重试队列
2. 重试策略:指数退避(1s, 2s, 4s, 8s)最多3次
3. 最终失败 → 标记failed + 告警
4. 死信队列:多次重试失败的消息存入
流量控制:
1. 推送渠道QPS限制(令牌桶算法)
2. 动态调整发送速率
3. 渠道不可用时暂停发送
技术:Go, PostgreSQL, Redis Stream, 令牌桶, React
  • 大量推送任务正确拆分
  • worker并发消费正常
  • 推送进度实时准确
  • 失败自动重试(指数退避)
  • 死信队列正确存储
  • 令牌桶限流生效
  • 渠道恢复后自动继续发送
  • 消息队列削峰 → Module: 消息队列
  • 批量任务拆分 → Module: 分布式计算
  • 指数退避重试 → Module: 容错机制
  • 令牌桶限流 → Module: 流量控制

推送太多用户就关通知了,需要智能控制推送频率和时机,提高效果。

  • 最佳发送时间预测
  • 频率控制防骚扰
  • 个性化推送内容
  • A/B测试优化
在V5基础上实现智能推送系统:
最佳发送时间:
1. 记录每个用户的APP活跃时间段
2. 统计分析:用户最常打开通知的时间段
3. 推送时不立即发送,等到用户活跃时间段再发
4. 兜底:超过24小时未发送则强制发送
频率控制:
1. 全局规则:每个用户每天最多5条推送
2. 渠道规则:同一渠道每小时最多2条
3. 类型规则:营销类每周最多3条
4. 优先级队列:重要通知(交易、安全)不受限
5. 被抑制的推送记录原因
个性化:
1. 用户兴趣标签 → 推送内容匹配
2. 标题A/B变体生成
3. 按用户历史点击偏好选择内容风格
A/B测试:
1. 创建实验:指定变体(标题A vs 标题B)
2. 流量分配:50/50随机分组
3. 效果对比:各变体的点击率、转化率
4. 统计显著性计算(卡方检验)
5. 自动胜出:达到显著性后自动选择优胜变体
技术:Go微服务, PostgreSQL, Redis, 统计分析, React
  • 活跃时间段统计准确
  • 推送在用户活跃时间发出
  • 频率控制正确限制各维度
  • 重要通知不被频率控制拦截
  • A/B测试流量均匀分配
  • 点击率统计准确
  • 显著性判断合理
  • 被抑制推送有记录和原因
  • 用户行为分析 → Module: 数据分析
  • 频率控制(多维限流)→ Module: 流量控制
  • A/B测试与统计显著性 → Module: 实验平台
  • 个性化推荐基础 → Module: 推荐系统