RabbitMQ--集成Springboot--06--SpringRetry重试

RabbitMQ–集成Springboot–06–SpringRetry重试


1、介绍

rabbitMQ有个方法channel.basicNack()能够让消息回到队列中,这样可以实现重试。但是这样没有明确重试次数,如果当前的消息一直重试的话,则后面的消息就会堆积起来,导致后面的消息无法消费。

这是一个致命的缺点。因此这就需要设置重试次数来解决这种问题。下面提供几种解决方案。

  1. 使用redis或者mongo等第三方存储当前重试次数。
  2. 在header中添加重试次数,并且使用channel.basicPublish() 方法重新将消息发送出去后将重试次数加1。
  3. 使用spring-rabbit中自带的retry功能

2、手动确认模式说明

  1. 监听的方法内部必须使用channel进行消息确认,包括消费成功或消费失败
  2. 如果不手动确认,也不抛出异常,消息不会自动重新推送(包括其他消费者),因为对于rabbitmq来说始终没有接收到消息消费是否成功的确认,并且Channel是在消费端有缓存的,没有断开连接
  3. 如果rabbitmq断开,连接后会自动重新推送(不管是网络问题还是宕机)
  4. 如果消费端应用重启,消息会自动重新推送
  5. 如果消费端处理消息的时候宕机,消息会自动推给其他的消费者
  6. 如果监听消息的方法抛出异常,消息会按照listener.retry的配置进行重发,但是重发次数完了之后还抛出异常的话,消息不会重发(也不会重发到其他消费者),只有应用重启后会重新推送。因为retry是消费端内部处理的,包括异常也是内部处理,对于rabbitmq是不知道的(可使用死信队列)
  7. spring.rabbitmq.listener.retry配置的重发是在消费端应用内处理的,不是rabbitqq重发
  8. 可以配置MessageRecoverer对异常消息进行处理,此处理会在listener.retry次数尝试完并还是抛出异常的情况下才会调可以配置MessageRecoverer对异常消息进行处理,默认有两个实现

2.1、配置MessageRecoverer


//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);
    }
}

2.2、retry yml配置


  rabbitmq:
    username: guest
    password: guest
    port: 5672
    host: localhost
    publisher-confirms: true #  消息发送到交换机确认机制,是否确认回调
    publisher-returns: true  #  消息发送到交换机确认机制,是否返回回馈
    listener:       # 开启ACK
      direct:
        acknowledge-mode: manual
      simple:
        acknowledge-mode: manual
        retry:
          enabled: true         #  允许消息消费失败的重试
          max-attempts: 6       # 消息最多消费次数6次
          initial-interval: 1000ms # 消息多次消费的间隔1秒
          max-interval: 1200000ms #重试最大时间间隔(单位毫秒)
          multiplier: 2 #应用于上一重试间隔的乘数 即重试时间为  上次重试时间*2
          stateless: true
          default-requeue-rejected: false  #  设置为false,会丢弃消息或者重新发布到死信队列

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值