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);
}
相关推荐
lang201509288 小时前
Spring Boot优雅关闭全解析
java·spring boot·后端
刘一说9 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
lang2015092810 小时前
Spring Boot缓存机制全解析
spring boot·后端·缓存
摇滚侠11 小时前
Spring Boot 3零基础教程,WEB 开发 默认页签图标 Favicon 笔记29
java·spring boot·笔记
lang2015092811 小时前
Spring Boot SQL数据库全攻略
数据库·spring boot·sql
是梦终空12 小时前
计算机毕业设计241—基于Java+Springboot+vue的爱心公益服务系统(源代码+数据库+11000字文档)
java·spring boot·vue·毕业设计·课程设计·毕业论文·爱心公益系统
泉城老铁16 小时前
springboot 对接发送钉钉消息,消息内容带图片
前端·spring boot·后端
qq_124987075316 小时前
基于Spring Boot的高校实习实践管理系统(源码+论文+部署+安装)
java·spring boot·后端·毕业设计
韩宁羽16 小时前
SpringBoot开发双11商品服务系统[完结19章]
spring boot
5pace18 小时前
【JavaWeb|第二篇】SpringBoot篇
java·spring boot·后端