- A+
在开发中,我们期望消息的发送与业务系统进行解耦,这样做的好处是,可以是业务代码与消息系统的发送完全分离,不会因为消息发送的快慢程度而影响业务系统处理。因此,我们使用队列来完成消息的推送。
消息流程图:
① 创建消息类型队列
在之前我们将消息按类型分类,例如:财务消息、文章消息、审核消息等,同样,我们可以根据业务拆分为几个业务队列,用来存储消息推送的参数。
② 推送参数存入队列
在业务触发消息推送后,我们可以将推送的一些参数,使用func_get_args()获取参数并存入业务队列。
③ 将消息ID和推送目标用户存入推送渠道队列
在业务队列出队列后,我们可以将一些参数如:跳转信息、跳转参数等存入数据库,并将推送目标和消息ID存入渠道队列
④ 消息推送并记录推送结果
在渠道队列出队列后,我们根据渠道完成消息的推送,并记录推送结构。
下面我们进行数据库实体设计:
消息类型表 (message_type):
name | 字段 | 数据类型 | 备注 |
msg_type_id | msg_type_id | int | 消息类型主键,自增 |
消息类型名称 | msg_type_name | varchar | |
消息类型ICON | msg_type_icon | varchar | |
消息类型队列 | msg_type_queue | varchar |
用于存储消息类型以及其对应的队列名称,如 : {msg_type_id : 1, msg_type_name: '财务消息', msg_type_icon: '', msg_type_queue:'q:msg_type:finance'}
消息动作表 (message_action):
name | 字段 | 数据类型 | 备注 |
action_id | action_id | int | 主键 |
动作名称 | action_name | varchar(30) | |
消息类型 | msg_type_id | int | 外键 |
用于记录触发消息推送的动作表,将来如果需要做用户消息订阅,可以从此表取数据,并做扩展表实现消息订阅。
消息模板表 (message_tpl)
name | 字段 | 数据类型 | 备注 |
msg_tpl_id | msg_tpl_id | int | 主键 |
模板名称 | msg_tpl_name | varchar(10) | |
模板内容 | msg_tpl_content | varchar(200) | |
模板参数 | msg_tpl_vars | varchar(100) | 模板参数,用逗号分割 |
推送渠道 | push_channel | int | 对应的推送渠道ID |
action_id | action_id | int | 外键 |
用于存储提醒消息和验证码消息的内容,因为某个动作触发需要对多个渠道进行消息推送,所以单独一张表处理。
消息中间表(message)
name | 字段 | 数据类型 | 备注 |
message_id | message_id | int | 主键 |
推送渠道 | push_channels | varchar(100) | 多个,用逗号分割 |
消息类型 | message_type | tinyint | 1提醒消息2自定义消息3验证码 |
action_id | action_id | int | 外键 |
接收人类型 | receiver_type | int | 1按人推送 2按角色推送 |
msg_type_id | msg_type_id | int | 外键 |
对于提醒消息和验证码消息: 在推送参数出业务队列即第三步中,我们将一部分参数存入此表, push_channels 来源于 message_tpl 中的推送动作所关联的所有渠道。
对于自定义消息: 由推送参数中决定推送渠道和msg_type_id。
消息接收人表(message_receiver)
name | 字段 | 数据类型 | 备注 |
message_receiver_id | message_receiver_id | int | 主键 |
message_id | message_id | int | 外键 |
接收人 | receiver_id | int | 角色ID/用户ID |
数据源 | data_source | text | 数据源,用户替换模板中的参数 |
用于存储消息的接收人信息和额外的数据。
在进推送渠道队列之前,如果接收人类型是角色, 则将角色ID转换为user_id
消息推送记录表 (message_push_log)
name | 字段 | 数据类型 | 备注 |
push_log_id | push_log_id | int | 主键 |
user_id | user_id | int | 接收人 |
channel_id | channel_id | int | 推送的渠道 |
推送结果 | push_result | text | |
message_id | message_id | int | 外键 |
推送状态 | push_status | int | 1成功 -1失败 |
web消息 (web_sned_message)
name | 字段 | 数据类型 | 备注 |
send_id | send_id | int | 主键 |
消息标题 | web_message_title | varchar(200) | |
消息内容 | web_message_content | text | |
消息类型 | web_message_type | int | 消息类型 1消息 2公告 |
user_id | user_id | int | 用户ID 消息时使用 |
roles_ids | roles_ids | varchar(200) | 角色ID 多个 逗号分割 公告使用 |
阅读量 | read_nums | int | 阅读量 |
推送状态 | push_status | int | 1成功 -1失败 |
message_id | message_id | int | 外键 |
web消息表,记录表, 在出渠道web消息队列后,存储到此表。
公告不进行推送,直接存储到此表。
消息阅读表 (message_read)
name | 字段 | 数据类型 | 备注 |
read_id | read_id | int | 主键 |
user_id | user_id | int | |
send_id | send_id | int | 外键 |
阅读状态 | read_status | int | 0未读1已读 |
阅读时间 | read_time | datetime |
在web消息推送成功后,记录到此表,用户登录成功后,拉取此表消息记为未读消息,阅读后修改状态。
公告:在用户登录后,拉取用户对应角色的公告到此表作为未读公告,阅读后修改状态。
公告流程图: