跳转到内容

14. Notification System 通知系统

你做了一个待办事项应用,需要在页面内展示通知(如任务到期提醒),用badge显示未读数。

用纯前端实现通知列表、未读计数、标记已读,数据存localStorage。

帮我用纯HTML+JavaScript实现一个前端通知系统:
1. 通知数据结构:
- {id, type, title, message, read, created_at}
- 类型:info, warning, success, error
2. UI组件:
- 右上角铃铛图标 + 红色未读badge
- 点击铃铛展开通知下拉列表
- 每条通知显示图标、标题、时间、已读状态
- 点击通知标记为已读,badge数减1
- "全部标已读"按钮
3. 通知触发模拟:
- 页面上有按钮模拟不同事件触发通知
- "任务到期" → warning通知
- "任务完成" → success通知
- "系统公告" → info通知
4. 存储:localStorage持久化,刷新保留
5. 动画:新通知到达时铃铛晃动动画,toast弹出3秒自动消失
不用框架,纯原生JS+CSS实现。
  • 未读badge数字正确
  • 点击通知标为已读
  • 全部标已读后badge消失
  • 刷新页面通知保留
  • 新通知有toast弹出
  • 通知系统的基础数据模型 → Module: 数据建模
  • 前端状态管理(未读计数同步) → Module: 状态管理
  • CSS动画基础 → Module: 前端交互

应用有了后端和多个用户,需要服务器主动推送通知到浏览器,而不是前端轮询。

用Go后端实现SSE(Server-Sent Events)推送通知,SQLite存储通知记录。

帮我用Go+Gin+SQLite实现SSE通知推送:
1. 数据模型:
- notifications表:id, user_id, type, title, message, read, created_at
2. SSE推送实现:
- GET /api/notifications/stream — SSE连接
- 服务端维护map[user_id]chan Notification
- 用户连接时注册channel,断开时清理
- 新通知产生时向目标用户的channel发送
3. REST API:
- GET /api/notifications — 获取通知列表(支持分页)
- PUT /api/notifications/:id/read — 标记已读
- PUT /api/notifications/read-all — 全部标已读
- DELETE /api/notifications/:id — 删除通知
4. 前端SSE接收:
- EventSource连接服务端
- 收到通知后更新列表和badge
- 断线自动重连
5. 触发通知的场景模拟:
- POST /api/notifications/send — 管理员发送通知给指定用户
- 支持发送给单个用户或所有用户(广播)
注意SSE的连接管理:用户关闭页面后channel要被清理。
  • 打开两个浏览器标签,给用户A发通知,只有A收到
  • 广播通知所有在线用户都收到
  • 关闭标签页后channel被清理
  • 断线后自动重连并收到期间通知
  • SSE vs WebSocket vs 轮询的选型 → Module: 实时通信
  • Go channel在连接管理中的应用 → Module: Go并发模式
  • 服务端推送的连接生命周期管理 → Module: 长连接管理

用户反馈只有站内通知不够,重要消息需要邮件通知。不同用户想选择自己的通知方式。

实现站内信+邮件双渠道通知,用户可配置通知偏好。

在V2基础上扩展多渠道通知:
1. 通知渠道:
- 站内信:SSE推送(已有)
- 邮件:SMTP发送
2. 邮件发送:
- 用Go net/smtp或第三方库
- 开发环境用MailHog模拟(docker-compose.yml)
- HTML邮件模板(Go html/template)
3. 用户通知偏好:
- notification_preferences表:user_id, channel, event_type, enabled
- 事件类型:task_due, task_assigned, system_announce, weekly_digest
- 每种事件可独立开关站内信和邮件
4. API:
- GET /api/notification-preferences — 获取当前用户偏好
- PUT /api/notification-preferences — 更新偏好
5. 通知分发逻辑:
- 产生通知事件 → 查用户偏好 → 按偏好分发到对应渠道
- 邮件发送失败时记录日志,不影响站内信
6. 前端设置页面:
- 表格形式:行=事件类型,列=渠道,单元格=开关
提供MailHog的docker-compose配置用于开发测试。
  • 站内信和邮件同时送达
  • 关闭邮件渠道后只收到站内信
  • MailHog能看到发出的邮件
  • HTML邮件模板正确渲染
  • 邮件发送失败不影响站内信
  • 多渠道通知的抽象设计(策略模式) → Module: 设计模式
  • SMTP协议和邮件发送 → Module: 邮件系统
  • 用户偏好系统设计 → Module: 个性化配置

V4 — 1000个用户:消息队列异步发送

Section titled “V4 — 1000个用户:消息队列异步发送”

用户量增长后,发送通知(尤其是邮件)变慢,阻塞了业务逻辑。需要异步化通知发送。

引入消息队列异步处理通知,支持模板引擎和批量推送。

在V3基础上引入消息队列异步通知:
1. 消息队列:
- 使用Redis Stream作为消息队列(不引入Kafka/RabbitMQ)
- 生产者:业务代码发送通知事件到Stream
- 消费者:独立goroutine消费Stream,执行实际发送
2. 消息结构:
- {event_type, user_ids, template_id, variables, channels}
- 支持单发和群发
3. 模板引擎:
- 通知模板存数据库:template_id, channel, subject_tpl, body_tpl
- 变量替换:{{.UserName}}, {{.TaskTitle}}, {{.DueDate}}
- 站内信和邮件用不同模板
4. 批量推送优化:
- 群发通知时一条消息包含多个user_id
- 消费者端批量处理,邮件合并发送
- 发送进度跟踪:已发/总数
5. 失败处理:
- 发送失败的消息进入重试队列
- 最多重试3次,间隔递增(1s, 5s, 30s)
- 3次仍失败的进入死信队列,人工处理
6. 管理API:
- GET /api/admin/notifications/queue-stats — 队列积压量
- POST /api/admin/notifications/broadcast — 群发通知
提供docker-compose.yml包含Redis。
  • 发送通知接口立即返回,不阻塞
  • 消费者正确处理队列中的消息
  • 模板变量正确替换
  • 失败消息被重试
  • 群发1000人通知在合理时间内完成
  • 异步化的价值:解耦和削峰 → Module: 异步架构
  • Redis Stream作为轻量消息队列 → Module: 消息队列入门
  • 重试和死信队列设计 → Module: 可靠消息投递
  • 模板引擎的应用 → Module: 模板系统

用户同时用Web和手机,Web上已读的通知手机端还显示未读。需要多端通知状态实时同步。

WebSocket实时同步通知状态,预留移动端推送接口。

在V4基础上实现多端通知同步:
1. WebSocket通知通道(替代SSE):
- /ws/notifications — WebSocket连接
- 支持同一用户多个连接(多标签页/多设备)
- 连接管理:用户ID → []连接
2. 状态同步:
- 用户在设备A标记已读 → 通过WebSocket通知设备B更新
- 同步消息类型:new_notification, read, read_all, delete
- 离线期间的通知:重连后拉取未读列表
3. 移动端推送接口(预留):
- device_tokens表:user_id, platform(ios/android), token
- POST /api/devices/register — 注册设备token
- 推送接口封装:预留FCM/APNs调用位置,当前只记日志
4. 在线状态:
- 记录用户最后在线时间
- 只对在线用户走WebSocket,离线用户攒着等上线拉取
5. 连接心跳:
- 每30秒ping/pong
- 超时60秒未响应断开连接
6. 压测:模拟1000个WebSocket连接,发送广播通知
用gorilla/websocket库实现。
  • 两个标签页通知状态实时同步
  • 一端标已读另一端同步更新
  • 断线重连后收到离线期间通知
  • 心跳超时自动断开
  • 1000连接广播通知正常送达
  • WebSocket连接管理和Hub模式 → Module: WebSocket实战
  • 多端状态同步的一致性挑战 → Module: 实时同步
  • 移动推送生态(FCM/APNs) → Module: 移动端推送

用户抱怨通知太多太烦。有人一天收到50封邮件。需要智能化通知:聚合、优先级、频率控制。

实现通知聚合(digest)、优先级排序、频率控制,减少通知打扰。

设计并实现智能通知系统:
1. 通知聚合(Digest):
- 相似通知合并:"有3个人评论了你的帖子"
- 聚合规则:按event_type+target_id分组,时间窗口内合并
- 邮件digest:每天一封汇总邮件,而非每条单独发
- 用户可选择digest频率:实时/每小时/每天
2. 优先级排序:
- 通知优先级:urgent(立即送达), high(1小时内), normal(digest), low(仅计数)
- 优先级规则引擎:
- 被@提及 → urgent
- 被回复 → high
- 被点赞 → normal
- 系统公告 → low
3. 频率控制:
- 每种渠道每小时最多N条(用户可配置)
- 超过阈值的降级到digest
- 夜间免打扰模式(22:00-08:00只存不发)
4. A/B测试框架:
- 测试不同通知文案对点击率的影响
- 按用户分桶,记录送达率、打开率、点击率
- 实验配置和结果分析API
5. 数据统计面板:
- 各渠道送达率、打开率、点击率
- 通知发送量趋势图
- 用户退订率和投诉率
重点实现聚合引擎和频率控制逻辑。
  • 5条相似通知聚合为1条
  • urgent通知立即送达,normal进digest
  • 超过频率限制的通知被降级
  • 夜间免打扰时段不推送
  • A/B测试分桶正确,结果可查询
  • 通知聚合的设计(时间窗口+分组) → Module: 流式数据处理
  • 优先级队列和规则引擎 → Module: 规则系统设计
  • A/B测试的工程实现 → Module: 实验平台
  • 用户体验和通知疲劳 → Module: 产品思维