基于RabbitMq的服务异步通讯消息重试

使用消息队列是为了能高性能的将消息从publisher处传递到consumer处,但是在传递过程中可能会出现一些问题导致消息没有被正常消费导致消息丢失。

在RabbitM中,消息从publisher发出到达交换机,在由交换机路由到消息队列中,最后到达消费者,当消费者接收消息后进行处理,如果此时消费者出现异常,就会不断的requeue(重新进入队列)再次发送给消费者,陷入循环,如果消息量过大,还会给Rabbitmq带来不必要的压力,因此,我们可以利用Springretry机制,在消费者出现异常时利用本地重试,即直接在本地进行重试操作,而不是无限制的requeuemq队列,在application.yml中加入以下配置

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1
        retry:
          enabled: true  //开启消费者retry重试机制
          max-attempts: 3  //重试最大次数
          initial-interval: 1000 //第一次失败后等待时长
          multiplier: 3.0  //每次失败后等待时长的翻倍数
          stateless: true //true无状态;false有状态。如果业务中包含事务,这里改为false

如果重试后消息仍然处理失败,默认情况下那么消费者给publisher返回reject(拒绝),这时消息会从队列中被删去,消息也就发送失败了,当然我们也可也通过实现MessageRecoverer接口来实现其他操作

RejectAndDontRequeueRecoverer :重试耗尽后,直接 reject ,丢弃消息。默认就是这种方式
ImmediateRequeueMessageRecoverer :重试耗尽后,返回 nack ,消息重新入队,之后该消息不被发送,等待人工处理
RepublishMessageRecoverer :重试耗尽后,将失败消息投递到指定的交换机

 在publisher中定义一个配置类,用进行处理失败的消息统一处理,在这里我们实现RepublishMessageRecoverer,

@Configuration
public class ErrorConfig {
     //创建一个专门处理失败消息的交换机error.direct
    @Bean
    public DirectExchange errorExchange() 
    {
        return new DirectExchange("error.direct");
    }
    //创建一个存储失败消息的队列error.queue
    @Bean
    public Queue errorQueue() 
    {
        return new Queue("error.queue",true); //设置队列持久化
    }
    //将error.direct和error.queue绑定起来,并指定对应的routingkey:error
    @Bean
    public Binding errorBind() 
    {
        return BindingBuilder.bind(errorExchange()).to(errorExchange()).with("error");
    }
    // 实现MessageRecover接口的子类RepublishMessageBulider
    @Bean  
    public MessageRecoverer republishMessageBuilder(RabbitTemplate rabbitTemplate)
    {
        return new RepublishMessageRecoverer(rabbitTemplate,"error.direct","error");
    }
}

这样,在消息处理抛出异常后,在本地进行重试结束后,消息就不会丢失了,而是会被发送到error.queue队列中去,我们就可以进行人工的干预了,避免因产生异常导致消息丢失或者RabbitMq压力增大

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值