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);
    }
相关推荐
Vesan,7 小时前
网络通讯知识——通讯分层介绍,gRPC,RabbitMQ分层
网络·分布式·rabbitmq·无人机
卿着飞翔1 天前
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
java·rabbitmq·java-rabbitmq
计算机毕设定制辅导-无忧学长1 天前
从 AMQP 到 RabbitMQ:核心组件设计与工作原理(二)
网络·rabbitmq·ruby
itachi-uchiha1 天前
命令行以TLS/SSL显式加密方式访问FTP服务器
服务器·网络协议·ssl
moppol1 天前
SSL/TLS握手全流程拆解:从“Hello“到“安全通道“的每一个字节
网络·安全·ssl
itachi-uchiha1 天前
使用vsftpd搭建FTP服务器(TLS/SSL显式加密)
运维·服务器·ssl
Think Spatial 空间思维2 天前
【实施指南】Android客户端HTTPS双向认证实施指南
android·网络协议·https·ssl
'tubug'2 天前
数字证书_CA_详解
https·ssl
锐成19192 天前
FTPS、HTTPS、SMTPS以及WebSockets over TLS的概念及其应用场景
网络协议·https·ssl
找不到、了2 天前
深入学习RabbitMQ队列的知识
分布式·rabbitmq