java mq 补偿_RabbitMQ整合Spring Booot【消费者补偿幂等问题】

本文介绍了在Java中使用RabbitMQ时,如何处理消费者运行时异常并实现补偿机制。RabbitMQ默认提供重试机制,当消费者处理消息时抛出异常,消息会持续尝试消费,直到不抛异常为止。文章讨论了不同场景下是否需要重试,并给出了日志记录加定时任务补偿的解决方案。此外,还详细展示了如何设置消费者重试策略,以及如何通过全局Message ID确保幂等性。最后,提到了手动应答模式在消费者端的应用,以确认消息已被正确消费。
摘要由CSDN通过智能技术生成

如果消费者 运行时候 报错了

packagecom.toov5.msg.SMS;importorg.springframework.amqp.rabbit.annotation.RabbitHandler;importorg.springframework.amqp.rabbit.annotation.RabbitListener;importorg.springframework.stereotype.Component;

@Component

@RabbitListener(queues="fanout_sms_queue")public classSMSConsumer {

@RabbitHandlerpublic voidprocess(String mString) {

System.out.println("短信消费者获取生产者消息msg"+mString);int i = 1/0;

}

}

当生产者投递消息后:

消费者会不停的进行打印:

ba1e68811a1414fac6848e110b014ec8.png

消息一直没有被消费

bc3c1333da5bc2ebc88654ce9fbce6b5.png

原因 Rabbitmq 默认情况下 如果消费者程序出现异常情况 会自动实现补偿机制  也就是 重试机制

@RabbitListener底层使用AOP进行拦截,如果程序没有抛出异常,自动提交事务。 如果Aop使用异常通知 拦截获取异常信息的话 , 自动实现补偿机制,该消息会一直缓存在Rabbitmq服务器端进行重放,一直重试到不抛出异常为准。

可以修改重试策略

一般来说默认5s重试一次,

消费者配置:

listener:

simple:

retry:

####开启消费者重试

enabled: true

####最大重试次数(默认无数次)

max-attempts: 5

####重试间隔次数

initial-interval: 3000

效果: 充实5次 不行就放弃了

fe75addec6d3b2d08140d4698d2a7760.png

8fb257dfb625d8d5a0856554527d2c18.png

MQ重试机制机制 需要注意的问题

如何合适选择重试机制

情况1:  消费者获取到消息后,调用第三方接口,但接口暂时无法访问,是否需要重试?

需要重试   别人的问题不是我自己的问题

情况2:  消费者获取到消息后,抛出数据转换异常,是否需要重试?

不需要重试   充实一亿次也是如此 木有必要  需要发布版本解决

总结:

对于情况2,如果消费者代码抛出异常是需要发布新版本才能解决的问题,那么不需要重试,重试也无济于事。应该采用 日志记录+定时任务job健康检查+人工进行补偿

把错误记录在日志里面,通过定时Job去自动的补偿,或通过人工去补偿。

传统的HTTP请求 如果失败了没法自动重试 ,当然自己可以写个循环实现。MQ完全自己自带的。

情况2的拓展延申:

将之前的案例改为   邮件消费者 调用邮件第三方接口

伪代码:

在consumer 中 调用接口后 判断返回值  由于RabbitMQ 在消费者异常时候 会进行重试机制 进行补偿

所以可以抛出个异常 来实现

Consumer:

String result   =   template.Email();

if(result == null){

throw new Exception("调用第三方邮件服务器接口失败!");

}

producer:

ffb1b094be957bbca3d2aea81956c260.png

pom:

4.0.0

com.itmayiedu

rabbitmq_producer_springboot

0.0.1-SNAPSHOT

org.springframework.boot

spring-boot-starter-parent

2.0.0.RELEASE

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-amqp

org.apache.commons

commons-lang3

com.alibaba

fastjson

1.2.49

config:

packagecom.itmayiedu.rabbitmq.config;importorg.springframework.amqp.core.Binding;importorg.springframework.amqp.core.BindingBuilder;importorg.springframework.amqp.core.FanoutExchange;importorg.springframework.amqp.core.Queue;importorg.springframework.context.annotation.Bean;importorg.springframework.stereotype.Component;//Fanout 类型 发布订阅模式

@Componentpublic classFanoutConfig {//邮件队列

private String FANOUT_EMAIL_QUEUE = "fanout_email_queue";//短信队列

private String FANOUT_SMS_QUEUE = "fanout_sms_queue";//fanout 交换机

private String EXCHANGE_NAME = "fanoutExchange";//1.定义邮件队列

@BeanpublicQueue fanOutEamilQueue() {return newQueue(FANOUT_EMAIL_QUEUE);

}//2.定义短信队列

@BeanpublicQueue fanOutSmsQueue() {return newQueue(FANOUT_SMS_QUEUE);

}//2.定义交换机

@Bean

FanoutExchange fanoutExchange() {return newFanoutExchange(EXCHANGE_NAME);

}//3.队列与交换机绑定邮件队列

@Bean

Binding bindingExchangeEamil(Queue fanOutEamil

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值