当前位置: 首页>后端>正文

spring rabbitmq 发送信息卡顿 rabbitmq 如何保证消息发送成功

数据的丢失问题,可能出现在生产者、MQ、消费者中

要保证两个进程间通信正常,可以采用下面介绍的一些方法

如果场景是:服务A产生一些数据需要服务B去做排序,A通过mq通知服务B执行;这种情况,也可以通过定时rpc调用做兜底,服务B定时去做排序,如果数据没准备好,就轮空一次,这样可以确保当mq消息丢失,不影响业务进行,但可能排序没那么及时

生产者丢失

生产者将数据发送给rabbitmq的时候,由于网络等原因,数据可能在半路丢失

方案1:

可以选择用rabbitmq提供的事务功能,生产者发送数据之前开启rabbitmq事务channel.txSelect,然后发送消息,如果消息没有成功被rabbitmq接收到,生产者会收到异常报错,此时可以回滚事务channel.txRollback,然后重试发送消息;如果收到了消息,可以提交事务channel.txCommit

缺点:吞吐量会下降,因为很耗性能

方案2:

一般情况下,如果要保证rabbitmq不丢消息,可以开启confirm模式,在生产者那里设置开启confirm模式之后,每次写的消息都会分配一个唯一的id,如果写入了rabbitmq中,rabbitmq会回传一个ack消息,表示这个消息收到了。如果rabbitmq没能处理这个消息,会回复nack,告诉你这个消息接收失败,可以重试(rabbitmq异步回调)

以上两种方案最大的不同,事务机制是同步的,提交一个事务之后会阻塞在那,但confirm机制是异步的,发送这个消息后可以发送下一个消息,通常生产者都会使用方案2

MQ中丢失

rabbitmq自己弄丢了数据,这种必须开启rabbitmq的持久化,消息写入之后会持久化到磁盘,如果rabbitmq自己挂了,重启之后会自动读取之前之前存储的数据,一般数据不会丢。

设置持久化有两个步骤:

  1. 创建queue的时候将其持久化,这样就可以保证rabbitmq持久化queue的元数据,但是不会持久化queue里的数据 (将queue的durable=true)
  2. 发送消息时将消息的deliverymode设置为2,将消息设置为持久化的,这时rabbitmq会将消息持久化到磁盘

必须同时设置上面两个持久化才行,rabbitmq重启会从磁盘上恢复queue,恢复queue里的数据

持久化可以和生产者那边的confirm机制配合起来,在消息持久化到磁盘后,才会通知生产者ack,如果在持久化到磁盘之前mq挂了,数据丢了,但是生产者收不到ack,生产者重发消息

消费端丢失

消费的时候,刚消费到,还没处理,结果进程挂了,rabbitmq认为你已经消费了,这数据就丢了。这时候要用rabbitmq提供的ack机制,关闭rabbitmq的自动ack,可以通过一个api来调用,消费者自己代码里确保处理完的时候,在程序里ack

总结:

rabbitmq消息丢失及对应解决方案

生产者:

方案1,开启rabbitmq事务(同步,不推荐)

方案2,开启confirm模式(异步,推荐)

MQ:

开启rabbitmq持久化(队列持久化、消息持久化)

消费者:

关闭rabbitmq自动ack


https://www.xamrdz.com/backend/3dy1931248.html

相关文章: