请教有关RabbitMQ消息确认的问题

2024-05-07 16:28

1. 请教有关RabbitMQ消息确认的问题

下面是RabbitMQ的消息确认机制:

“为了确保消息不会丢失,RabbitMQ支持消息确认机制。客户端在接受到消息并处理完后,可以发送一个ack消息给RabbitMQ,告诉它该消息可以安全的删除了。假如客户端在发送ack之前意外死掉了,那么RabbitMQ会将消息投递到下一个consumer客户端。如果有多个consumer客户端,RabbitMQ在投递消息时是轮询的。RabbitMQ如何判断客户端死掉了?唯一根据是客户端连接是否断开。这里没有超时机制,也就是说客户端可以处理一个消息很长时间,只要没断开连接,RabbitMQ就一直等待ack消息。”
我现在遇到的问题是这样的:我这边有几条线程去消息队列里取数据,但是会有异常数据导致线程挂掉,就是上边的“客户端在发送ack之前意外死掉了”,RabbitMQ会将消息投递到下一个consumer客户端,这样一条异常数据会把我的所有线程挂掉,我现在想实现这样的功能:如果有异常数据导致进程挂掉,那么我不让RabbitMQ将这条消息投递到下一个consumer客户端,而是放到另一个地方或者另外处理,请问该如何实现呢?

请教有关RabbitMQ消息确认的问题

2. RabbitMQ(一)--关于消息通信

1.生产者:创建消息,发布消息到代理服务器(RabbitMQ)
   (1)消息:有效荷载和标签
   (2)有效荷载:消息的内容
   (3)标签:用来描述消息(交换器的名称或者可选主题的标记),然后把消息交由RabbitMQ,由RabbitMQ进行后续处理
   2.消费者:连接到代理服务器(RabbitMQ),并订阅到队列(queue)上,接收代理服务器发布的消息并读取
   (1)接收到的消息只包括有效荷载,即消息内容
  
 1.基本原理:首先创建一条TCP连接,TCP连接打开后(即通过认证),应用程序创建一条AMQP信道。
   2.信道:是建立在真实的TCP连接内的虚拟连接,AMQP命令是通过信道发送出去
   3.应用程序和RabbitMQ代理之间的连接用信道而不直接用TCP连接的原因
   (1)一个信道处理一个线程,一个TCP连接可以承载多个信道,即多个线程可以使用同一个TCP连接,减少资源消耗,避免性能瓶颈
   (2)一个TCP的创建和销毁对资源的消耗会很大,创建需要三次握手,销毁需要四次挥手。
   4.TCP协议的三次握手和四次分手
   (1)建立连接的三次握手:
   -第一次握手:客户端发送给服务端,请求连接
   -第二次握手:服务端接收到客户端发送的请求连接的消息,回复给客户端请求连接
   -第三次握手:上述两次握手本质上已经建立连接,但是此时客户端还会发送给服务端一个消息,确认连接,即表示连接成功
   (2)销毁连接的四次挥手:
   -第一次挥手:客户端发送给服务端,断开连接
   -第二次挥手:服务端接收到请求断开连接的请求,发送确认消息
   -第三次挥手:服务端发送给客户端,断开连接
   -第四次挥手:客户端接收到服务端的消息,确认断开连接
   注意:销毁连接需要四次挥手是因为TCP连接是双向连接,断开也需要双向断开和确认

3. RabbitMQ 的消息确认机制(含代码实现)

 哈喽大家好,我是阿Q!
   上文,我们已经完成了SpringBoot快速集成RabbitMQ的小Demo,本文我们来聊一下RabbitMQ为了防止消息丢失,增加的消息确认机制:生产者消息确认机制和消费者消息确认机制。
    一、生产者消息确认机制 
   大家可以自行演示以下情况的执行结果:
    二、消费者消息的确认机制 
     消费者消息的确认机制可以分为以下3种:
   AcknowledgeMode.NONE 默认为自动确认,不管消费者是否成功处理了消息,消息都会从队列中被移除。
   AcknowledgeMode.AUTO 根据方法的执行情况来决定是否确认还是拒绝(是否重新入队列)
   可能造成消息丢失,一般是需要我们在try-catch捕捉异常后, 打印日志 用于追踪数据,这样找出对应数据再做后续处理。
   AcknowledgeMode.MANUAL对于手动确认,也是我们工作中最常用到的,它的用法如下:
   在yml配置中开启手动确认模式
   或者在代码中开启
   消息消费类
     作者:阿Q说代码  链接:https://juejin.cn/post/7063259228898590750    

RabbitMQ 的消息确认机制(含代码实现)