rabbit mq中的坑,消费端错误造成的死循环

周五上线pre,发现mq消费端的调用的一个服务不停的报错,很快就把磁盘空间打满了,一开始以为是job死循环,当时确实也发现循环处有问题,修正循环处后,重新发布到pre环境发现还是有同样的问题,此时感觉很痛苦。通过仔细查看错误日志发现错误处是由rabbitmq 消费端报出来了,一时没有明白是什么原因,随找rabbitmq管理员,管理员说有消息一直没有消费掉,rabbitmq会一直重复投送消息,这样导致的链路的死循环。

总结:关于rabbit mq 没有死信队列,接受消息时,即消费端,如果抛出异常,则消息消耗不掉,rabbitmq会一直不停的投送消息,这样从整个链路上形成了死循环。业务错误暂且不论,这样仅仅错误日志就会把磁盘耗光,这点千万注意。

RabbitMQ ,当消费者接收到消息后,可以通过手动确认机制告诉 RabbitMQ 已经处理完成,RabbitMQ 会将该消息从队列删除。如果消费者在处理消息时发生异常或者其他错误,可以将该消息重新放回队列,让其他消费者重新消费。 具体实现上,可以在消息监听器使用 `Channel` 对象调用 `basicReject` 或 `basicNack` 方法将消息重新放回队列,或者使用 `basicAck` 方法确认处理完成。 以下是一个简单的消息监听器示例,实现了当消息处理失败时将消息重新放回队列: ``` @Component public class MessageListener { @Autowired private RabbitTemplate rabbitTemplate; @RabbitListener(queues = "myQueue") public void handleMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException { try { // 处理消息,如果发生异常出 // ... // 手动确认消息接收 channel.basicAck(deliveryTag, false); } catch (Exception e) { // 消息处理失败,重新放回队列 channel.basicNack(deliveryTag, false, true); // 或者使用 basicReject 方法将消息重新放回队列 // channel.basicReject(deliveryTag, true); // 发送告警消息 rabbitTemplate.convertAndSend("alarmExchange", "alarmRoutingKey", "Failed to handle message: " + message); } } } ``` 在上面的代码,当处理消息时发生异常时,我们使用 `basicNack` 方法将消息重新放回队列,并发送一条告警消息。如果不需要告警可以直接使用 `basicReject` 方法将消息重新放回队列。 需要注意的是,当使用手动确认机制时,需要在 RabbitMQ 设置 `autoAck` 参数为 `false`,即不自动确认消息接收。否则,如果消费者在处理消息时出现异常,消息会被自动确认,RabbitMQ 将无法将其重新放回队列
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值