RabbitMQ 可靠性、重复消费、顺序性、消息积压解决方案

本文详细探讨了RabbitMQ在消息可靠性、重复消费、顺序性和消息积压等方面的解决方案。介绍了如何设置消费者应答机制,避免消费者丢失消息,并提供了处理消息重复消费的两种策略。同时,分享了在生产环境中遇到的问题和实践经验,强调了在确保消息顺序性和处理异常时的注意事项。
摘要由CSDN通过智能技术生成

rabbitTemplate.setReturnsCallback(returned -> {

//记录日志、发送邮件通知、落库定时任务扫描重发

});

}

}

测试的时候可以在发送消息时故意写错交换机、路由键的名称,然后就会回调到我们刚刚写的监听方法, cause 会给我们展示具体没有发到交换机的原因;returned 对象中包含了消息相关信息。

实际上据我了解一些企业并不会在这两个监听里面去做重发,为什么呢?成本太高了…首先 RabbitMQ 本身丢失的可能性就非常低,其次如果这里需要落库再用定时任务扫描重发还要开发一堆代码,分布式定时任务…再其次定时任务扫描肯定会增加消息延迟,不是很有必要。真实业务场景是记录一下日志就行了,方便问题回溯,顺便发个邮件给相关人员,如果真的极其罕见的是生产者弄丢消息,那么开发往数据库补数据就行了。

RabbitMQ 弄丢消息

========================================================================

不开启持久化的情况下 RabbitMQ 重启之后所有队列和消息都会消失,所以我们创建队列时设置持久化,发送消息时再设置消息的持久化即可(设置 deliveryMode 为 2 就行了)。一般来说在实际业务中持久化是必须开的。

消费者弄丢消息

==================================================================

所谓消费端弄丢消息就是消费端执行业务代码报错了,那么该做的业务其实没有做。比如创建订单成功了,优惠券结算报错了,默认情况下 RabbitMQ 只要把消息推送到消费者就会认为消息已经被消费,就从队列中删除了,但是优惠券还没有结算,这样就相当于消息变相丢失了。这种情况还是很常见的,毕竟我们开发人员不能保证自己的代码不报错,这种问题一定得解决。 否则用户下了订单,优惠券没有扣减,你这个月的绩效估计是没了…

RabbitMQ 给我们提供了消费者应答(ack)机制,默认情况下这个机制是自动应答,只要消息推送到消费者就会自动 ack ,然后 RabbitMQ 删除队列中的消息。启用手动应答之后我们在消费端调用 API 手动 ack 确认之后,RabbitMQ 才会从队列删除这条消息。

首先在配置文件中开启手动 ack

spring:

rabbitmq:

listener:

simple:

acknowledge-mode: manual #手动应答

然后在消费端代码中手动应答签收消息

@RabbitListener(queues = “queue”)

public void listen(String object, Message message, Channel channel) {

long deliveryTag = message.getMessageProperties().getDeliveryTag();

log.info(“消费成功:{},消息内容:{}”, deliveryTag, object);

try {

/**

  • 执行业务代码…

  • */

channel.basicAck(deliveryTag, false);

} catch (IOException e) {

log.error(“签收失败”, e)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值