RabbitMq手动确认时的重试机制
本文转载自RabbitMq手动确认时的重试机制
消息手动确认模式的几点说明
监听的方法内部必须使用channel进行消息确认,包括消费成功或消费失败
如果不手动确认,也不抛出异常,消息不会自动重新推送(包括其他消费者),因为对于rabbitmq来说始终没有接收到消息消费是否成功的确认,并且Channel是在消费端有缓存的,没有断开连接
如果rabbitmq断开,连接后会自动重新推送(不管是网络问题还是宕机)
如果消费端应用重启,消息会自动重新推送
如果消费端处理消息的时候宕机,消息会自动推给其他的消费者
如果监听消息的方法抛出异常,消息会按照listener.retry的配置进行重发,但是重发次数完了之后还抛出异常的话,消息不会重发(也不会重发到其他消费者),只有应用重启后会重新推送。因为retry是消费端内部处理的,包括异常也是内部处理,对于rabbitmq是不知道的(此场景解决方案后面有)
spring.rabbitmq.listener.retry配置的重发是在消费端应用内处理的,不是rabbitqq重发
可以配置MessageRecoverer对异常消息进行处理,此处理会在listener.retry次数尝试完并还是抛出异常的情况下才会调用,默认有两个实现:
- RepublishMessageRecoverer:将消息重新发送到指定队列,需手动配置,如:
@Bean
public MessageRecoverer messageRecoverer(RabbitTemplate rabbitTemplate){
return new RepublishMessageRecoverer(rabbitTemplate, "exchangemsxferror", "routingkeymsxferror");
}
- RejectAndDontRequeueRecoverer:如果不手动配置MessageRecoverer,会默认使用这个,实现仅仅是将异常打印抛出,源码如下:
public class RejectAndDontRequeueRecoverer implements MessageRecoverer {
protected Log logger = LogFactory.getLog(RejectAndDontRequeueRecoverer.class);
@Override
public void recover(Message message, Throwable cause) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Retries exhausted for message " + message, cause);
}
throw new ListenerExecutionFailedException("Retry Policy Exhausted", new AmqpRejectAndDontRequeueException(cause), message);
}
}
- 可以通过给队列(Queue)绑定死信队列,使用nack反馈给mq,会将消息转发到死信队列里面,此种方式需要自己在消费消息的方法内部将异常处理掉
//声明队列,并给队列增加x-dead-letter-exchange和x-dead-letter-routing-key参数,用于指定死信队列的路由和routingKey
@Bean
public Queue queue(){
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-dead-letter-exchange",IntegralConstant.DEAD_EXCHANGE_NAME);
args.put("x-dead-letter-routing-key",IntegralConstant.DEAD_ROUTING_KEY);
return new Queue(IntegralConstant.QUEUE_NAME, true, false, false, args);
}
//消息确认时使用nack,并且requeue参数传false
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
- 消息变成死信有以下几种情况:
- 消息被拒绝(basic.reject/ basic.nack)并且requeue=false
- 消息TTL过期(参考:RabbitMQ之TTL(Time-To-Live 过期时间))
- 队列达到最大长度
总结
- 消息监听内必须使用channel对消息进行确认,不管是确认消费成功还是确认消费失败
- 消息监听内的异常处理有两种方式:
- 内部catch后直接处理,然后使用channel对消息进行确认
- 配置RepublishMessageRecoverer将处理异常的消息发送到指定队列专门处理或记录
- 监听的方法内抛出异常貌似没有太大用处。因为抛出异常就算是重试也非常有可能会继续出现异常,当重试次数完了之后消息就只有重启应用才能接收到了,很有可能导致消息消费不及时。当然可以配置RepublishMessageRecoverer来解决,但是万一RepublishMessageRecoverer发送失败了呢。。那就可能造成消息消费不及时了。所以即使需要将处理出现异常的消息统一放到另外队列去处理,个人建议两种方式:
- catch异常后,手动发送到指定队列,然后使用channel给rabbitmq确认消息已消费
- 给Queue绑定死信队列,使用nack(requque为false)确认消息消费失败
RabbitMq手动确认时的重试机制的更多相关文章
- 使用rabbitmq手动确认消息的,定时获取队列消息实现
描述问题 最近项目中因为有些数据,需要推送到第三方系统中,因为数据会一直增加,并且需要与第三方系统做相关交互. 相关业务 本着不影响线上运行效率的思想,我们将增加的消息放入rabbitmq,使用另一个 ...
- [转载]rabbitmq可靠发送的自动重试机制
转载地址http://www.jianshu.com/p/6579e48d18ae http://www.jianshu.com/p/4112d78a8753 接这篇 在上文中,主要实现了可靠模式的c ...
- rabbitmq 不发送ack消息如何处理:rabbitmq可靠发送的自动重试机制
转载地址:http://www.jianshu.com/p/6579e48d18ae http://www.jianshu.com/p/4112d78a8753 接这篇 在上文中,主要实现了可靠模式的 ...
- jmeter-利用While Controller控制器实现接口报错时的重试机制
预期功能:在jmter脚本报错的时候重试,最多重试5次 1.添加While Controller 2.添加请求 3.添加断言,在断言不符合预期的时候加上代码:vars.put("status ...
- 要做重试机制,就只能选择 DelayQueue ?其实 RabbitMQ 它上它也行!
原文链接:要做重试机制,就只能选择 DelayQueue ?其实 RabbitMQ 它上它也行! 一.场景 最近研发一个新功能,后台天气预警:后台启动一条线程,定时调用天气预警 API,查询现有城市的 ...
- rabbit mq 手动重试机制
消息手动确认模式的几点说明 监听的方法内部必须使用channel进行消息确认,包括消费成功或消费失败 如果不手动确认,也不抛出异常,消息不会自动重新推送(包括其他消费者),因为对于rabbitmq来说 ...
- RabbitMQ消息确认机制
文章目录 1. 事务机制2. Confirm模式2.1 生产者2.1.1 普通Confirm模式2.1.2 批量Confirm模式2.1.3 异步Confirm模式2.2 消费者3. 其他 消费者如何 ...
- 【独家】完美解决appium安装app时,需要手动确认安装的问题
appium初始化driver时,如果未安装该app会先进行安装,安装时,很多安卓手机都会弹框,需要手动确认安装. 如小米的机器, 这是个头疼的问题,之前在网上找遍了,只有通过adb去点相对坐标成功了 ...
- rabbitmq学习(八) —— 可靠机制上的“可靠”
接着上一篇,既然已经有了手动ack.confirm机制.return机制,还不够吗? 以下博文转自https://www.jianshu.com/p/6579e48d18ae和https://my.o ...
随机推荐
- 免费开源的代码审计工具 Gosec 入门使用
声明: 本教程是在自己的电脑上本地测试Gosec的效果,所以不涉及其他运行模式,如果想要了解其他模式可以关注后期文档,如果想要自定义交流自定义代码扫描规则,可以跟我交流沟通. 背景: Gosec是一个 ...
- CCF CSP 202012-1 期末预测之安全指数
202012-1 期末预测之安全指数 题目背景 期末要到了,小菜同学找到了自己的好朋友顿顿,希望可以预测一下自己这学期是否会挂科. 题目描述 首先,顿顿选取了如"课堂表现".&qu ...
- charles(3)charles防止30分钟自动重启
前言 Charles是收费软件,可以免费试用30天.试用期过后,未付费的用户仍然可以继续使用,但是每次使用时间不能超过30分钟,并且启动时将会有10秒种的延时. 此时,我们只需网上找一个注册码即可 解 ...
- centos7.2安装图形化界面 && 在Linux上更改当前默认界面
安装环境 [root@desktop-test ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 安装过程 [root@ ...
- Codeforces #Round 632 div2 A~C
A. Little Artem Young boy Artem tries to paint a picture, and h ...
- HDU 1173 思路题
题目大意 有n个地点(坐标为实数)需要挖矿,让选择一个地点,使得在这个地方建造基地,到n个地点的距离和最短,输出基地的坐标. 题解+代码: 1 /* 2 把这个二维分开看(即把所有点投影到x轴上,再把 ...
- PowerShell启用多跳远程控制
有些场景下,我们使用远程连接了某个Server,在远程Server中再想进行远程操作,就会提示错误.因为默认的认证信息只会传递一跳. 对此,微软官方文档给出的解决方案是:https://docs.mi ...
- 5.PowerShell DSC核心概念之资源
什么是资源? 资源为 DSC 配置提供构建基块. 资源公开可配置的属性,并包含本地配置管理器 (LCM) 调用以"使其如此"的 PowerShell 脚本函数. 系统内置资源 可在 ...
- 梨子带你刷burp练兵场(burp Academy) - 服务器篇 - Sql注入 - SQL injection UNION attack, determining the number of columns returned by the query
目录 SQL injection UNION attack, determining the number of columns returned by the query SQL injection ...
- CF1474-C. Array Destruction
CF1474-C. Array Destruction 题意: 题目给出一个长度为\(2n\)的正整数序列,现在问你是否存在一个\(x\)使得可以不断的进行如下操作,直到这个序列变为空: 从序列中找到 ...