使用mq消息队列来进行下单流程的高并发设计,消息挤压,消息丢失,消息重复的产生场景和解决方案

使用消息队列来进行下单流程的高并发设计

使用消息队列来进行下单流程的高并发设计

使用消息队列的话就要解决一个核心的问题,那就是如何保证消息的可靠性,有以下三种解决办法,在微服务架构的项目中并发高的业务不能用seata来进行分布式事务的处理,所以使用消息队列来确保数据的最终一致性。使用消息事务的柔性事务:可靠消息+最终一致性方案(异步确保型)

消息丢失

发送给mq的消息在那些场景下会丢失:

1、由于网络波动,网络闪断导致消息没有抵达服务器,没有发出去,可以在发送消息的地方进行try catch,要保证消息一定会发送出去,将发送失败的消息做好日志记录,每个消息状态是否都被服务器收到都应该记录,并且应该将这个消息存储到持久化存储的数据库中比如mysql数据库等。并且做好定期重发,如果消息没有发送成功,定期去数据库扫描未成功的消息进行重发。

给每个数据库中创建一个mq_message消息表,用于存放发送的消息,给数据库保存每一个消息的详细信息,保存了之后只要发送失败了,就可以定期扫描数据库将失败的消息再发送一遍。

​
CREATE TABLE `mq_message` (
  `message_id` char(32) NOT NULL,        #消息的唯一id
  `content` text,      #消息的内容 转换成json
  `to_exchane` varchar(255) DEFAULT NULL,  #发给的那个交换机
  `routing_key` varchar(255) DEFAULT NULL,   #发送的路由键是什么
  `class_type` varchar(255) DEFAULT NULL,    #标志消息的类型
  `message_status` int(1) DEFAULT '0' COMMENT '0-新建 1-已发送 2-错误抵达 3-已抵达',
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`message_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

​2、消息抵达了Broker,Broker要将消息写入磁盘(持久化)才算成功,此时Broker尚未持久化完成,宕机。mq服务器收到消息之后一定要持久化保存,然后再将消息发送给交换机,交换机再交给指定的队列。

除了消费消息有确认机制,发送消息也有确认机制,可靠抵达-ConfirmCallback

消息抵达Queue后, 才算消息抵达成功,publisher也必须加入确认回调机制,确认成功的消息,然后修改数据库对应消息的状态。

3、自动ACK的状态下,消费者收到消息,但没来得及消费消息,消费者服务器就宕机了,导致消息丢失,所以一定要开启手动ACK,消费成功才移除,失败或者没来得及处理就noAck重新入队。

以上三点其实可以归属成一点,就是做好消息确认机制(发送端和消费端都要确认消息的抵达和消费),每一个发送的消息都在数据库做好记录,定期将失败的消息再次发送一遍。
​​​​在这里插入图片描述
消息抵达Queue后, 才算消息抵达成功,publisher也必须加入确认回调机制,确认成功的消息,然后修改数据库对应消息的状态。

3、自动ACK的状态下,消费者收到消息,但没来得及消费消息,消费者服务器就宕机了,导致消息丢失,所以一定要开启手动ACK,消费成功才移除,失败或者没来得及处理就noAck重新入队。

以上三点其实可以归属成一点,就是做好消息确认机制(发送端和消费端都要确认消息的抵达和消费),每一个发送的消息都在数据库做好记录,定期将失败的消息再次发送一遍。

消息重复

消息重复就是一个消息给消费者发了两遍,相当于消费者消费了两次

场景:

1、消费者在执行完核心代码后,事务已经提交,ack时,服务器宕机了,导致没有给mq进行回应,没有ack成功,因为开启的是手动ACK,所以消息队列会认为失败,Broker的消息重新由unack变为ready,并发送给其它消费者,再次发送消息,但是消费者已经执行完核心代码了,这样就造成了重复的消费

2、消息消费失败,由于重试机制,自动又将消息发送出去,这个是正常的场景
在这里插入图片描述
消息成功消费,但是ack时宕机,消息由unack变为ready,Broker又重新发送给消费者,导致消息消费重复,解决办法就是将和核心业务设计成幂等即可,用每个消息的唯一ID来记录是否已执行完核心业务(提交事务后),将消息唯一ID的状态标志为已消费,再次消费时根据唯一ID来判断是否可以消费。

消息积压

消息积压就是,消息队列里面的消息太多,肯定会影响mq的性能,带来mq的性能下降

场景:

1、消费者宕机,mq没有连到任何一个消费者,或者连的太少了,没有消费者来消费消息了,生产者也在不停的产生消息

2、发送的流量太大,mq存了太多的消息

解决:

1、上线更多的消费者,进行正常消费

2、如果业务量太大,数据量太大,那就可以上线一个专门用于处理消息的消费者,这个消费者将mq里面的消息全部取出来,然后存入数据库,自己编写一个离线处理业务,一条一条处理数据库中的消息

总结

消息丢失是最需要避免的,这一块需要闭环

最后上一张用于下单流程的消息队列高并发设计流程图,如下
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱敲代码的小松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值