RabbitMQ:生产者可靠性(生产者重连、生产者确认)

目录


一、生产者重连

当网络不稳定的时候,利用重试机制可以有效提高消息发送的成功率。不过SpringAMQP提供的重试机制是阻塞式的重试,也就是说多次重试过程中,当前线程是被阻塞的,会影响业务性能。

如果对于业务性能有要求,建议禁用重试机制。如果一定要使用,请合理配置等待时长和重试次数,当然也可以考虑异步线程来执行发送消息的代码。

yml 复制代码
spring:
	rabbitmq:
	  connection-timeout: 200ms  # 设置连接超时时间
	  template:
	    retry:
	      enabled: true  # 开启超时重试机制
	      initial-interval: 1000ms  # 失败后的初始等待时间
	      multiplier: 1  # 失败后下次的等待时长倍数,下次等待时长=initial-interval * multiplier
	      max-attempts: 3  # 最大重试次数

二、生产者确认

RabbitMQ有两种确认机制:Publisher ConfirmPublisher Return。开启确认机制后,在MQ成功收到消息后会返回确认消息给生产者,返回的结果有以下几种情况:

  1. 消息投递到了MQ,但是路由失败。此时会通过Publisher Return返回路由异常原因,然后返回ACK,告知投递成功。
  2. 临时消息投递给了MQ,并且入队成功,返回ACK,告知投递成功。
  3. 持久消息投递到MQ,并且入队成功,返回ACK,告知投递成功。
  4. 其他情况都会返回NACK,告知投递失败

在生产者服务YML文件中增加一下配置:

yml 复制代码
spring:
  rabbitmq:
    publisher-returns: true  # 开启publisher-return机制
    publisher-confirm-type: correlated  # 设置机制类型:异步

publisher-confirm-type有三种模式可选:

  • none:关闭confirm机制。
  • simple:同步阻塞等待MQ的回执消息。
  • correlated:MQ异步回调方式返回回执消息

每个RabbitTemplate只能配置一个ReturnCallback,因此需要在项目启动过程中配置:

java 复制代码
package com.ming.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class CommonConfig implements ApplicationContextAware {
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                log.error(String.format("ReturnsCallback:消息发送失败,应答码 %s,原因 %s,交换机 %s,路由键 %s,消息 %s ...", returnedMessage.getReplyCode(), returnedMessage.getReplyText(), returnedMessage.getExchange(), returnedMessage.getRoutingKey(), returnedMessage.getMessage()));
            }
        });
    }
}

发送消息,指定消息ID,消息ConfirmCallback,此回调每一次发送消息的时候都要指定:

java 复制代码
@Test
public void confirmCallbackTest() throws InterruptedException {
    // 1. 创建cd
    CorrelationData cd = new CorrelationData();
    // 2. 增加ConfirmCallback
    cd.getFuture().addCallback(new ListenableFutureCallback<CorrelationData.Confirm>() {
        @Override
        public void onFailure(Throwable throwable) {  // Spring消息回调失败
            log.warn("ConfirmCallback:Spring消息回调失败......", throwable);
        }
        @Override
        public void onSuccess(CorrelationData.Confirm confirm) {  // 消息发送回调
            if (confirm.isAck()) {
                log.info("ConfirmCallback:RabbitMQ 消息发送成功,收到ACK......");
            }else {
                log.warn("ConfirmCallback:RabbitMQ 消息发送成功,收到NACK......", confirm.getReason());
            }
        }
    });
    // 3. 发送消息
    rabbitTemplate.convertAndSend("mt.topic", "china.weather", "黄色警报 ......", cd);  // 成功例子
    // rabbitTemplate.convertAndSend("mt.topic", "aaa", "黄色警报 ......", cd);  // 失败例子
    Thread.sleep(2000);
}
相关推荐
JH307314 分钟前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
qq_12498707533 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_3 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
2301_818732064 小时前
前端调用控制层接口,进不去,报错415,类型不匹配
java·spring boot·spring·tomcat·intellij-idea
汤姆yu7 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
暮色妖娆丶7 小时前
Spring 源码分析 单例 Bean 的创建过程
spring boot·后端·spring
biyezuopinvip8 小时前
基于Spring Boot的企业网盘的设计与实现(任务书)
java·spring boot·后端·vue·ssm·任务书·企业网盘的设计与实现
JavaGuide9 小时前
一款悄然崛起的国产规则引擎,让业务编排效率提升 10 倍!
java·spring boot
figo10tf9 小时前
Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程
java·spring boot·后端
zhangyi_viva9 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端