设计一个消息中心
需求汇总
- 消息已读\未读
- 消息投递
- 展示消息数量
- 一键已读
- 多用户
- 推送的渠道
消息的分类
系统通知
系统通知一般是由后台管理员发出,然后指定某一类(全体,个人等)用户接收。 基于此设想,可以把系统通知大致分为两张表:
- 一张记录管理员发出的通知,称之为 t_manager_system_notice 管理员系统通知表;
- 一张存储用户接受的通知,称之为 t_user_system_notice 用户系统通知表。
这个 t_manager_system_notice 结构如下:
字段名 | 类型 | 描述 |
---|---|---|
system_notice_id | LONG | 系统通知ID |
title | VARCHAR | 标题 |
content | TEXT | 内容 |
type | VARCHAR | 发给哪些用户:单用户single;全体用户all,vip用户,具体类型各位同学可以根据自己的需求选择 |
state | BOOLEAN | 是否已被拉取过,如果已经拉取过,就无需再次拉取 |
recipient_id | LONG | 接受通知的用户的ID,如果type为单用户,那么recipient为该用户的ID;否则recipient为0 |
manager_id | LONG | 发布通知的管理员ID |
publish_time | TIMESTAMP | 发布时间 |
这个 t_user_system_notice 结构如下:
字段名 | 类型 | 描述 |
---|---|---|
user_notice_id | LONG | 主键ID |
state | BOOLEAN | 是否已读 |
system_notice_id | LONG | 系统通知的ID |
recipient_id | LONG | 接受通知的用户的ID |
pull_time | TIMESTAMP | 拉取通知的时间 |
当管理员发布一条通知后,将通知插入 t_manager_system_notice 表中,然后系统定时的从 t_manager_system_notice 表中拉取通知,然后根据通知的 type 将通知插入 t_user_system_notice 表中。
如果通知的 type 是 single 的,那就只需要插入一条记录到 t_user_system_notice 中。如果是全体用户,那么就需要将一个通知批量根据不同的用户 ID 插入到 t_user_system_notice 中, 这个数据量就需要根据平台的用户量来计算。
举个例子: 管理员A 发布了一个活动的通知,他需要将这个通知发布给全体用户, 当拉取时间到来时,系统会将这一条通知取出。随后系统到用户表中查询选取所有用户的 ID, 然后将这一条通知的信息根据所有用户的 ID,批量插入 t_user_system_notice 中。 用户需要查看系统通知时,从 t_user_system_notice 表中查询就行了。
个人消息
TODO: 遇到再设计
设计方案
方案1:提供 sdk 没有 MQ
优点:
- 降低了系统的复杂度;
缺点:
- 需要保证消息中心的并发、高可用等各种复杂场景;
方案2:提供sdk,借助 MQ
优点:
- 集成成本低,只要按照 sdk 接口封装消息调用即可,便于新手集成以及调试;
- 业务系统无需关注消息处理方式,不需要引入 mq 组件;
- 消息中心统一选择 mq 组件,方便后期升级改造;
- 处理延迟消息时无需借助其他方案,比如定时器或者轮询;
- 削峰,有效保证消息中心能够始终稳定处理消息;
- 有效保证处理的顺序性;
缺点:
- 业务方需要集成 sdk,跟消息中心耦合在一起;
- 业务系统需要维护 sdk 的版本;
- 消息中心服务不可用时,消息无法正常发送,造成消息丢失;
- 引入 mq 后,增加了复杂度;
- 需要保证 mq 的可用性;
方案3:不提供sdk,借助 MQ
优点:
- 业务系统无需集成 sdk,跟消息中心完全解耦;
- 无需关注后续 sdk 升级等问题;
- 消息中心不可用时,不影响业务系统正常消息发送;
缺点:
- 使用成本高,新业务集成无法知道消息体包装是否正确,中间的调试排查成本高;
- 业务系统需要引入 mq 等配置信息和组件,增加了业务系统的复杂度;
- 不利于后期对 mq 的升级改造;
SDK 方法设计
发送方式
- 单个发送消息(可以考虑去掉)
- 批量发送消息
撤回方式
- 单个消息撤回(可以考虑去掉)
- 批量消息撤回
发送形式
- 短信
- 站内信
- 邮件
消息管理
消息类型列表接口
根据端标识来展示消息类型列表
列表中要包含:类型信息+最新消息+未读数量
消息类型下消息列表分页接口
查询消息类型下的所有消息,需要分页展示、排序
未读数量接口-总合计
查询用户所有未读的消息合计
已读接口
修改消息阅读状态
删除接口
消息逻辑删除