rabbit mq 手动重试机制
消息手动确认模式的几点说明
监听的方法内部必须使用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)确认消息消费失败
rabbit mq 手动重试机制的更多相关文章
- Rabbit MQ 消息确认和持久化机制
一:确认种类 RabbitMQ的消息确认有两种.一种是消息发送确认,用来确认生产者将消息发送给交换器,交换器传递给队列的过程中消息是否成功投递.发送确认分为两步,一是确认是否到达交换器,二是确认是否到 ...
- RabbitMq手动确认时的重试机制
本文转载自RabbitMq手动确认时的重试机制 消息手动确认模式的几点说明 监听的方法内部必须使用channel进行消息确认,包括消费成功或消费失败 如果不手动确认,也不抛出异常,消息不会自动重新推送 ...
- 分布式消息中间件Rabbit Mq的了解与使用
MQ(消息队列)作为现代比较流行的技术,在互联网应用平台中作为中间件,主要解决了应用解耦.异步通信.流量削锋.服务总线等问题,为实现高并发.高可用.高伸缩的企业应用提供了条件. 目前市面比较流行的消息 ...
- Rabbit MQ config文件解析
Rabbit MQ config文件解析 tcp_listeners:用于监听AMQP连接的端口或主机名/对(不带TLS),默认端口:5672 2.numtcpacceptors :将接受TCP侦听器 ...
- rabbit MQ 消息队列
为什么会需要消息队列(MQ)? 一.消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ...
- celery rabbit mq 详解
Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, ...
- RocketMQ-消费重试机制
介绍: RocketMQ的消息重试及时分为两种,一种是Producer端重试,一种是Consume端重试. 1.Producer端重试 : 1.1消息发没发成功,默认情况下是3次重试. 2.Consu ...
- SpringCloud | FeignClient和Ribbon重试机制区别与联系
在spring cloud体系项目中,引入的重试机制保证了高可用的同时,也会带来一些其它的问题,如幂等操作或一些没必要的重试. 今天就来分别分析一下 FeignClient 和 Ribbon 重试机制 ...
- Rocket重试机制,消息模式,刷盘方式
一.Consumer 批量消费(推模式) 可以通过 consumer.setConsumeMessageBatchMaxSize(10);//每次拉取10条 这里需要分为2种情况 Consumer端先 ...
随机推荐
- bootstrap-table 常用总结-树形结构
关于树形结构,上篇文章如果还是不能理解的话,请看这一篇.把其他的没有用到的功能都去掉,只留最基础的树形结构! 废话不多说,直接上代码!所有的数据都是走的本地,如果大家想改的话可以自己改,但是需要注意的 ...
- angular8自定义管道、指令以及获取dom值
版本: 1.自定义管道: example: 定义一个*ngFor 可以获取key值的管道 keyObject.pipe.ts // key value 管道 import { Pipe, PipeTr ...
- Vue之富文本tinymce爬坑录
前言 最近因业务需求在项目中嵌入了tinymce这个富文本编辑器,用于满足平台给用户编辑各类新闻内容什么的业务需求,前后也花了不少时间体验和对比了市面上各类开源编辑器. *案例demo版本:vue-t ...
- 4、netty第三个例子,建立一个tcp的聊天的程序
代码基于第二个例子,支持多客户端的连接,在线聊天. 主要思路: 连接建立时,在服务器端,保存channel 对象,当有新的客户端加入时,遍历保存的channel集合,向其他客户端发送加入消息. 当一个 ...
- color颜色大全
- OGG For Oracle To PostgreSQL
本文档描述OGG(Oracle goldengate)为Oracle同步到PostgreSQL数据库配置.在目前去“IOE”潮流.PostgreSQL确实是Oracle最好的替代品之一. 实验环境如下 ...
- python(二) jupyter 快捷键
jupyter notebook 中的快捷键介绍 当你熟练使用notebooks的基本功能后,掌握他的快捷键是十分必要的,这样可以大大提高你的工作效率.下面是一些比较常用的快捷键: 编辑模式:点击单元 ...
- python 导入同级目录文件时报错
当你import的时候,python解释器只会在sys.path这个变量(一个list,你可以print出来看)里面的路径中找可能匹配的package或module. 而一个package跟一个普通文 ...
- CSS画一个三角形,CSS绘制空心三角形,CSS实现箭头
壹 ❀ 引 这两天因为项目工作较少,闲下来去看了GitHub上关于面试题日更收录的文章,毕竟明年有新的打算.在CSS收录中有一题是 用css创建一个三角形,并简述原理 .当然对于我来说画一个三角形是 ...
- redis缓存穿透,缓存击穿,缓存雪崩
概念解释 redis 缓存穿透 key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源.比如用一个不存在的用户id获取用户信息,不论缓存还是数据库 ...