rabbitmq单向ssl认证配置与最佳实践(适用于各大云厂商)

背景

这里后补直接上代码

最佳实践

主要从两个方面保证消息不丢失

RabbitMQ方面

  1. 创建队列时开启持久化
  2. 创建交换器时开启持久化
  3. 创建镜像队列(可选)
  4. 开启延迟队列(可选)

代码层面

  1. 开启生产者到交换器回调参数
  2. 开启交换器到队列回调参数
  3. 开启消费者手动ack
  4. 注意消费端打印日志,考虑手动补偿(可选)

实现代码

RabbitMQ配置文件

java 复制代码
package com.jndj.core.config;

import com.rabbitmq.client.ConnectionFactory;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;


@Configuration
@EnableAutoConfiguration
public class RabbitMQAutoConfiguration {

    @Value("${spring.rabbitmq.host}")
    public String rmHost;

    @Value("${spring.rabbitmq.port}")
    public int rmPort;

    @Value("${spring.rabbitmq.username}")
    public String rmUsername;

    @Value("${spring.rabbitmq.password}")
    public String rmPassword;

    @Value("${spring.rabbitmq.virtual-host}")
    public String virtualHost;

    @Bean
    public CachingConnectionFactory connectionFactory() throws NoSuchAlgorithmException, KeyManagementException {
        ConnectionFactory rabbitConnectionFactory = new ConnectionFactory();
        rabbitConnectionFactory.setHost(rmHost);
        rabbitConnectionFactory.setPort(rmPort);
        rabbitConnectionFactory.setUsername(rmUsername);
        rabbitConnectionFactory.setPassword(rmPassword);
        rabbitConnectionFactory.setVirtualHost(virtualHost);
        rabbitConnectionFactory.useSslProtocol();
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(rabbitConnectionFactory);
        cachingConnectionFactory.setPublisherReturns(true);
        cachingConnectionFactory.setPublisherConfirms(true);
        return cachingConnectionFactory;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("ConfirmCallback:     " + "相关数据:" + correlationData);
                System.out.println("ConfirmCallback:     " + "确认情况:" + ack);
                System.out.println("ConfirmCallback:     " + "原因:" + cause);
            }
        });
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                System.out.println("ReturnCallback:     " + "消息:" + message);
                System.out.println("ReturnCallback:     " + "回应码:" + replyCode);
                System.out.println("ReturnCallback:     " + "回应信息:" + replyText);
                System.out.println("ReturnCallback:     " + "交换机:" + exchange);
                System.out.println("ReturnCallback:     " + "路由键:" + routingKey);
            }
        });
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        return rabbitTemplate;
    }

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(CachingConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return factory;
    }

}

生产者

java 复制代码
    public AjaxResult insertStuResults(@RequestBody MyoResults model) {
        try {
            rabbitTemplate.convertAndSend(RabbitMQConstant.EX_STU_RESULTS_MANUAL, RabbitMQConstant.Q_STU_RESULTS_MANUAL, model);
            return AjaxResult.success("上送成功");
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

消费者

java 复制代码
    @RabbitListener(queues = RabbitMQConstant.Q_STU_RESULTS_MANUAL)
    @RabbitHandler
    public void getManualMsg(Message message, Channel channel) throws IOException {
        String jsonString = new String(message.getBody(), StandardCharsets.UTF_8);
        ObjectMapper objectMapper = new ObjectMapper();
        MyoResults model = objectMapper.readValue(jsonString, MyoResults.class);
        iStuResultsService.insertMongodb(model);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
相关推荐
白驹过隙^^2 小时前
OB-USP-AGENT安装使用方法
数据库·经验分享·网络协议·tcp/ip·github·ssl
武子康4 小时前
Java-199 JMS Queue/Topic 集群下如何避免重复消费:ActiveMQ 虚拟主题与交付语义梳理
java·分布式·消息队列·rabbitmq·activemq·mq·java-activemq
Wang's Blog4 小时前
RabbitMQ: 消息过期机制与死信队列技术解析
rabbitmq
苦学编程的谢5 小时前
RabbitMQ_7_高级特性(4)
分布式·rabbitmq
赵榕6 小时前
RabbitMQ发布订阅模式同一消费者多个实例如何防止重复消费?
分布式·微服务·rabbitmq
柒儿吖10 小时前
官方适配完的命令行ruby在鸿蒙PC上的使用方法
开发语言·ruby·harmonyos
kite012111 小时前
Gin 与消息队列集成:使用 RabbitMQ 处理异步任务
golang·rabbitmq·gin
Wang's Blog1 天前
RabbitMQ: 消息可靠性保障机制深度解析与工程实践
rabbitmq
Wang's Blog1 天前
RabbitMQ: 全面安装与运维指南之从基础部署到高级配置
运维·分布式·rabbitmq
小坏讲微服务1 天前
Spring Boot4.0整合RabbitMQ死信队列详解
java·spring boot·后端·rabbitmq·java-rabbitmq