Rabbitmq可靠性消息投递两种方案(定时任务版本+延迟队列版本)
Rabbitmq可靠性消息投递 两种方案
每天多学一点点~
话不多说,这就开始吧…
1.前言
平时工作中用到的最后的消息队列就是rabbitmq。听说阿里云上还有amqp?哦,不错哟~这里提供两种可靠性消息的提供方案。在此记录一下!
2.定时任务版本+人工补偿
若真实的生产环境上, Biz_db(业务) 和 msg_db(消息) 是两个数据库,需要加 jta 监听,会有性能问题
消息状态
- 0 发送中
- 1 mq服务端签收消息成功
- 2 mq服务端签收消息失败
- 3 消费端消费消息成功
- 4 消费端消费消息失败
-----上游服务 开始 ------
-
生产者(order服务) 消息如入库 状态为0 Biz_db(业务) 和 msg_db(消息) 生产上一般要做两个数据库,存在分布式事务问题(jta解决)
因为是两个不同的数据库,所以存在 分布式事务(跨库事务) JTA 但性能会低 -
Product(order服务) 发送消息去 Mq-server
-
Mq-server 回调 消息可路由
-
判断 消息 是否可达
4.1 消息可达
ConfirmListener消息确定模式,判断ack
4.1.1 ack为true 更新msg_db(消息)状态为 1(mq服务签收消息成功)
4.1.2 ack为false 更新msg_db(消息)状态为 2(mq服务签收失败)4.2 消息不可达
ReutrnListener处理消息不可达的消息 去 msg_db(消息) 更新消息状态为 2(mq服务签收失败)
-----上游服务 结束 ------
-----下游服务 开始 ------
-
Mq-server发送消息给 er(product商品服务) 进行消费
-
Consumer(product商品服务) 判断消息 是否 异常 回调
6.1 Y异常 发送nack 更新 msg_db(消息)状态为 4(消息端签收失败) 是否要重回队列,看业务需求6.2 N正常 发送ack 更新 msg_db(消息)状态为 3(消息端签收消息)
-
定时抓取:消息表5分钟之内,消息状态不是3(消息端签收消息 也就是成功的)的消息
-----下游服务 结束 ------
3.延迟队列版本+人工补偿
消息状态
- 0 发送中
- 1 mq服务端签收消息成功
- 2 mq服务端签收消息失败
- 3 消费端消费消息成功
- 4 消费端消费消息失败
-
Product(order订单服务)业务数据biz_db入库
-
Product(order订单服务)发送消息去MQ-SERVER 这一步 失败 可以用 confirmListener 但是这一步失败的原因比较少
-
Product(order订单服务)发送延迟检查消息 可以与第二步间隔5min,具体根据业务需求
-
Consumer(product库存服务)监听业务消息 即监听 第二步 发送的消息
-
Consumer(product库存服务) 消费成功之后,发送确认消息 至 MQ-SERVER ,一定要比比 第三步 要快
-
Callback(回调检查服务) 监听第五步 确认消费消息
-
Callback(回调检查服务) 入库 第五步 发送的确认消费消息 msg_db
-
监听 第三步 发送的 延迟 检查消息 去msg_db查(通过消息id进行关联的) 若没查到,说明第五步 失败,去第九步延迟对比,重新发送
-
延迟检查对比 代码中没对比 直接跳到10 重新发送了
-
延迟检查失败,回调Product(order订单服务)服务重新发送消息
比起第一种方案:
- 优势 第一步不需要入msg_db,不需要加分布式事务jta,性能显著提高
- 劣势 增加了两个队列3,5两个队列 和 一个工程(Callback回调检查回复)
4.结语
世上无难事,只怕有心人,每天积累一点点,fighting!!!