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

embedded/2025/2/27 15:41:42/

背景

这里后补直接上代码

最佳实践

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

RabbitMQ方面

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

代码层面

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

实现代码

RabbitMQ配置文件

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;@Beanpublic 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;}@Beanpublic RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate();rabbitTemplate.setConnectionFactory(connectionFactory);rabbitTemplate.setMandatory(true);rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {@Overridepublic 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() {@Overridepublic 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;}@Beanpublic SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(CachingConnectionFactory connectionFactory) {SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);return factory;}}

生产者

    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());}}

消费者

    @RabbitListener(queues = RabbitMQConstant.Q_STU_RESULTS_MANUAL)@RabbitHandlerpublic 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);}

http://www.ppmy.cn/embedded/167564.html

相关文章

【HarmonyOS Next】鸿蒙状态管理V2装饰器详解

【HarmonyOS Next】鸿蒙状态管理V2装饰器详解 一、为什么需要V2状态管理装饰器? 首先我们需要了解什么是状态管理?在鸿蒙应用开发中,状态管理指的是,管理数据变化去刷新UI的整个过程。 举个例子,比如在界面中标题文…

SpringBoot——生成Excel文件

在Springboot以及其他的一些项目中&#xff0c;或许我们可能需要将数据查询出来进行生成Excel文件进行数据的展示&#xff0c;或者用于进行邮箱发送进行附件添加 依赖引入 此处demo使用maven依赖进行使用 <dependency><groupId>org.apache.poi</groupId>&…

【微信小程序】Source Map文件使用 快速定位错误位置

Source Map文件可以快速定位小程序报错位置&#xff0c;更方便解决问题&#xff0c;下面具体讲讲如何使用Source Map文件&#xff1a; 1.进入We分析后台&#xff08;https://wedata.weixin.qq.com/&#xff09;&#xff0c;左侧菜单&#xff1a;性能质量-JS分析&#xff0c;可以…

pytorch阶段性总结1

Dataset类,自定义数据集,想要使用这个类需要重写两个方法__init__和__getitem__ __init__可以用来初始化数据集所在位置的路径,__getitem__用来定义获取数据的方式 from torch.utils.data import Dataset from PIL import Image import os #自定义数据集简单示例 class MyDa…

CSS中选择器的优先级

通过不同的选择器,选中相同的元素,并且为相同的样式名设置不同的值时,就发生了样式的冲突.到底使用那个样式,如此就需要看优先级了. important!>行内样式 > ID选择器 > 类选择器 > 元素选择器 > 通配符选择器 1.选择器优先级分类 a类:ID选择器 b类:类,伪类,属…

Uniapp 中布局魔法:display 属性

一、开启 Uniapp 布局魔法之旅 各位 Uniapp 开发的小伙伴们&#xff0c;欢迎来到 Uniapp 这个充满创意和挑战的魔法世界&#xff01;在构建跨平台应用时&#xff0c;页面布局就像是搭建一座梦幻城堡&#xff0c;而 display 属性则是我们手中的神奇魔杖&#xff0c;能让元素们按…

FTP出现“打开 FTP 服务器上的文件夹时发生错误。请检查是否有权限访问该文件夹。”如何处理?

关闭“使用被动FTP”功能&#xff1a;在控制面板的“Internet选项”中&#xff0c;点击“高级”标签卡&#xff0c;找到“使用被动FTP&#xff08;为防火墙和DSL调制解调器兼容性&#xff09;”&#xff0c;并取消勾选124。 检查FTP服务器设置&#xff1a;确保FTP服务器没有开…

第47天:Web开发-JavaEE应用JNDI注入RMI服务LDAP服务DNS服务高版本限制绕过

#知识点 1、安全开发-JavaEE-JNDI注入-LADP&RMI&DNS等 2、安全开发-JavaEE-JNDI注入-项目工具&手工原理等 协议 作用 LDAP 轻量级目录访问协议&#xff0c;约定了 Client 与 Server 之间的信息交互格式、使用的端口号、认证方式等内容 RMI JAVA 远程方法协议&…