独立消息服务方案
- 实现思路:
- 预发送消息:主动方应用系统预发送消息,由消息服务子系统存储消息,如果存储失败,那么也就无法进行业务操作。如果返回存储成功,然后执行业务操作。
- 执行业务操作:执行业务操作如果成功的时候,将业务操作执行成功的状态发送到消息服务子系统。消息服务子系统修改消息的标识为“可发送”状态。
- 发送消息到实时消息服务:当消息的状态发生改变的时候,立刻将消息发送到实时消息服务中。接下来,消息将会被消息业务的消费端监听到,然后被消费。
- 消息状态子系统:相当于定时任务系统,在消息服务子系统中定时查找确认超时的消息,在主动方应用系统中也去定时查找没有处理成功的任务,进行相应的处理。
- 消息消费:当消息被消费的时候,向实时消息服务发送ACK,然后实时消息服务删除消息。同时调用消息服务子系统修改消息为“被消费”状态。
- 消息恢复子系统:当消费方返回消息的时候,由于网络中断等其他原因导致消息没有及时确认,那么需要消息恢复子系统定时查找出在消息服务子系统中没有确认的消息。将没有被确认的消息放到实时消息服务中,进行重做,因为被动方应用系统的接口是幂等的。
- 优点:
- 消息服务独立部署,独立维护,独立伸缩。
- 消息存储可以按需选择不同的数据库来集成实现。
- 消息服务可以被相同的的使用场景使用,降低重复建设服务的成本。
- 从分布式服务应用设计开发角度实现了消息数据的可靠性,消息数据的可靠性不依赖于MQ中间件,弱化了对MQ中间件特性的依赖。
- 降低了业务系统与消息系统之间的耦合,有利于系统的扩展维护。
- 缺点:
- 一次消息发送需要两次请求。
- 主动方应用系统需要实现业务操作状态的校验与查询接口。
(七)、消息服务子系统的设计实现
示例消息数据表:
名称 | 数据类型 | 允许空 | 默认值 | 属性 | 释义 |
---|---|---|---|---|---|
uuid | varchar(50) | No | — | unique | UUID |
version | int(11) | No | 0 | — | 版本号 |
editer | varchar(100) | Yes | NULL | — | 修改者 |
creater | varchar(100) | Yes | NULL | — | 创建者 |
edit_time | datetime | Yes | 0000-00-00 00:00:00 | — | 最后修改时间 |
create_time | datetime | No | 0000-00-00 00:00:00 | — | 创建时间 |
msg_id | varchar(50) | No | — | — | 消息ID |
msg_body | longtext | No | — | — | 消息内容 |
msg_date_type | varchar(50) | Yes | — | — | 消息数据类型 |
consumer_queue | varchar(100) | No | — | — | 消费队列 |
send_times | int(6) | No | 0 | — | 消息重发次数 |
is_dead | varchar(20) | No | — | — | 是否死亡 |
status | varchar(20) | No | — | — | 状态 |
remark | varchar(200) | Yes | — | — | 备注 |
field0 | varchar(200) | Yes | — | — | 扩展字段0 |
field1 | varchar(200) | Yes | — | — | 扩展字段1 |
field2 | varchar(200) | Yes | — | — | 扩展字段2 |