rabbitmq避免消息丢失和重复消费

1.生产者发送消息给mq时丢失
事务机制和confirm机制,事务机制是同步的,很消耗性能,常用的是confirm机制
事务机制:channel.txSelect   可开启事务,如果报错会回滚  channel.txRollback    如果没问题就提交   channel.txCommit
confirm机制:开启后,每个消息都会分配唯一的 id,mq如果收到会回传一个 ack消息,如果没有收到会回调你的一个 nack 接口,超过时间没接收到回调消息,生产者重发消息。

confirm机制是异步的,不接收回调也能继续发送下个消息,rabbitmq的回调也是异步的

2.在mq里发生丢失
首先在创建mq时开启持久化,然后发送消息的时候将消息的 deliveryMode 设置为 2,意思就是持久化,两步一起


3.发送消息给消费者时丢失

发送消息给消费者成功了,但如果就在此时,消费者的逻辑还没跑完,然后宕机了,那么这个消息就丢失了
关闭MQ的自动ack机制,通过一个 api 来调用就行,消费者的代码逻辑处理完,再在程序里 ack 。如果mq没有收到ack,证明这个消息没有被处理,可以继续发送给消费者



重复消费
 

  • 在消息生产时,MQ内部针对每条生产者发送的消息生成一个inner-msg-id,作为去重和幂等的依据(消息投递失败并重传),避免重复的消息进入队列;
  • 在消息消费时,要求消息体中必须要有一个bizId(对于同一业务全局唯一,如支付ID、订单ID、帖子ID等)作为去重和幂等的依据,避免同一条消息被重复消费
### RabbitMQ消息丢失解决方案 针对RabbitMQ中可能出现的消息丢失问题,存在多种有效的预防措施。生产者确认机制确保了每条消息确实被发送至目标队列;一旦生产者接收到Broker返回的成功通知,则表明消息已被正确接收[^3]。 #### 生产者确认机制 通过启用发布确认功能,生产者能够得知其发布的消息是否已经被代理接受并记录下来。这一步骤至关重要,因为只有当消息安全抵达Broker后才能继续执行下一步操作。具体实现方式是在Channel上设置`confirm.select()`方法来激活此特性,并监听相应的回调事件以捕捉确认状态变化。 ```java channel.confirmSelect(); // 发送消息... if (!channel.waitForConfirms()) { System.out.println("Message was not confirmed"); } ``` #### 持久化配置 为了进一步保障数据的安全性,在定义Queue时需指定消息属性为持久化的形式(`durable=true`),使得即使遇到意外断电等情况也能恢复未处理完毕的信息流。同时,Exchange与Binding也应当遵循相同的设定原则,从而构建起完整的可靠传输链路[^5]。 ```python channel.queue_declare(queue='task_queue', durable=True) properties=pika.BasicProperties(delivery_mode=2,) # make message persistent channel.basic_publish(exchange='', routing_key='task_queue', body=message, properties=properties) ``` --- ### 防止重复消费的方法 为了避免同一份内容被多个实例不当读取而造成逻辑错误的现象发生,引入了消费者级别的手动ACK机制作为核心手段之一。每当客户端成功解析一条指令之后再向服务器反馈确认信号,这样就能有效避免由于网络波动等原因引起的误判情形出现[^4]。 #### 手动应答模式 默认情况下,自动签收可能会引发潜在风险——即尚未真正完成的任务就被标记为已完成。因此建议采用显式的回执策略,允许应用程序自行控制何时才算正式结束一轮交互过程。下面给出了一段Python代码片段用于展示如何切换成这种更稳妥的方式: ```python def callback(ch, method, properties, body): try: process_message(body.decode()) ch.basic_ack(delivery_tag=method.delivery_tag) # 显式确认 except Exception as e: print(f"Failed to process message: {e}") ch.basic_nack(delivery_tag=method.delivery_tag) channel.basic_consume(queue='my_queue', on_message_callback=callback, auto_ack=False) ``` 此外,利用幂等性设计思路同样有助于缓解此类困扰。所谓幂等是指无论调用多少次相同的操作最终结果保持一致不变。例如在电商场景下更新商品库存数量时可以通过原子计数器或者版本号校验等方式达成目的。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值