1.默认情况下,如果消费者程序出现异常的情况下会自动实现补偿机制。
2.@RabbitListener
RabbitListener底层使用AOP拦截,如果程序没有抛出异常会自动提交事务,如果发生异常的话,会实现自动补偿机制,消息会缓存到RabbitMQ服务端进行存放,程序会一直尝试消费这条消息,直到程序不抛出异常为止。
3.重试机制配置:
#rabbitmq配置
rabbitmq:
####连接地址
host: 39.108.107.163
####端口号
port: 5672
####账号
username: root
####密码
password: root
### 地址
virtual-host: /distributeds
#重试机制设置
listener:
simple:
retry:
####开启消费者重试
enabled: true
####最大重试次数
max-attempts: 5
####重试间隔秒数(3s)
initial-interval: 3000
4.如何选择重试机制
如果消费者获取消息后,需要调用第三方接口,但接口暂时无法访问-----需要重试机制(根据接口的返回结果判断,如果结果异常(为空)直接抛出一个异常 ,RabbitListener底层使用AOP拦截进行重试)。
如果消费者获取消息后,消费者程序发生异常(数据转换异常,空指针异常等需要更新代码解决的)-----不需要重试机制(因为 重试还是会失败,应该采用日志记录消费失败的消息,然后进行人工补偿)
5.如何解决幂等性问题
产生原因:网络延迟传输中,会造成进行MQ重试中,在重试过程中,可能会造成重复消费。
解决办法:
使用全局MessageID,解决幂等性。
生产者生产消息的时候加上唯一的ID,并且把该ID存放到redis中,ID作为Key,value默认为0,消费者获取到消息ID后去redis中查询,如果value为0代表该消息没有被消费过,消费者消费完信息后将该ID的value改为1。