当前位置: 首页 > news >正文

SSM整合RabbitMQ,Spring4.x整合RabbitMQ

SSM整合RabbitMQ目录

  • 前言
  • 版本
  • 实现
    • 目录参考
    • pom.xml依赖
    • rabbitmq.properties配置文件
    • spring-rabbitmq.xml
    • spring-mvc.xml或applicationContext.xml
    • rabbitmq目录下
      • MessageConsumer.java
      • MessageConsumer2.java
      • MessageProducer.java
      • MessageConstant.java
    • 测试调用
  • 扩展
    • 消息重发
      • 方式一
      • 方式二
    • 多部署Tomcat下问题

前言

SSM框架整合RabbitMQ【比较简单,复制粘贴可用】
本人使用的Spring版本是4.x

版本

RabbitMQ相关
erl10.0.1
RabbitMQ3.7.9
安装步骤参考:https://www.cnblogs.com/saryli/p/9729591.html

相关依赖
spring4.0.2.RELEASE
spring-rabbit1.3.5.RELEASE

实现

目录参考

这是我整合时的项目结构
关键:rabbitmq文件包和rabbitmq.properties、spring-rabbitmq.xml、spring-mvc.xml
在这里插入图片描述

pom.xml依赖

在现成的SSM项目中整合

	<!--rabbitmq依赖 --><dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit</artifactId><version>1.3.5.RELEASE</version></dependency>

rabbitmq.properties配置文件

将 rabbitmq.properties配置文件添加到resources目录下

mq.host=127.0.0.1
mq.username=guest
mq.password=guest
mq.port=5672
mq.virtual-host=/

spring-rabbitmq.xml

将spring-rabbitmq.xml添加到resources目录下

<?xml version="1.0" encoding="UTF-8"?>
<beans 	xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:rabbit="http://www.springframework.org/schema/rabbit"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/rabbithttp://www.springframework.org/schema/rabbit/spring-rabbit-1.3.xsd"><!-- 引入连接配置文件 --><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">    <property name="location" value="classpath:rabbitmq.properties" /></bean> <!-- 定义rabbitmq connectionFactory连接工厂 --><rabbit:connection-factory id="connectionFactory"username="${mq.username}"password="${mq.password}" host="${mq.host}" port="${mq.port}"virtual-host="${mq.virtual-host}" /><!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 --><rabbit:admin id="connectAdmin" connection-factory="connectionFactory" /><!--定义queue队列 --><rabbit:queue name="queueTest" durable="true" auto-delete="false" exclusive="false" declared-by="connectAdmin" /><rabbit:queue name="queueTest1" durable="true" auto-delete="false" exclusive="false" declared-by="connectAdmin" /><!-- 定义direct exchange(也就是交换机),绑定queueTest队列(queueTest名称可以自定义) --><rabbit:direct-exchange name="exchangeTest" durable="true" auto-delete="false" declared-by="connectAdmin"><rabbit:bindings><rabbit:binding queue="queueTest" key="queueTestKey"></rabbit:binding><rabbit:binding queue="queueTest1" key="queueTestKey1"></rabbit:binding></rabbit:bindings></rabbit:direct-exchange><!--定义rabbit template用于数据的接收和发送 将amqpTemplate对象绑定exchange中交换机--><rabbit:template id="amqpTemplate" connection-factory="connectionFactory" exchange="exchangeTest" /><!-- 消息接收处理 --><bean id="messageReceiver" class="com.rabbitmq.MessageConsumer"></bean><bean id="messageReceiver1" class="com.rabbitmq.MessageConsumer2"></bean><!-- queue litener 观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象(监听),acknowledge="manual"设置消息手动确认(手动确认需要配合ack,不设置默认自动确认)  --><rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual"><rabbit:listener queues="queueTest" ref="messageReceiver" /><rabbit:listener queues="queueTest1" ref="messageReceiver1" /></rabbit:listener-container><!-- 扫描注入使用注解实例对象 --><context:component-scan base-package="com.rabbitmq" /></beans>

spring-mvc.xml或applicationContext.xml

我这里使用的spring-mvc.xml,根据自己配置文件使用

<import resource="classpath:spring-rabbitmq.xml" />

将这个import引入添加到 spring-mvc.xml 里的最前面,如果不添加到前面可能会报错
在这里插入图片描述

rabbitmq目录下

这个目录下的java文件已在spring-rabbitmq.xml中进行扫描注入

MessageConsumer.java

说明:MessageConsumer和MessageConsumer2其实都可以使用同一个类,修改xml指向即可,但是分开明了些

package com.rabbitmq;import java.nio.charset.Charset;import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;/*** @Title消息消费者* @date 2023/10/8*/
public class MessageConsumer implements MessageListener {@Overridepublic void onMessage(Message message) {// 逻辑处理System.out.println("message------->:" + new String(message.getBody(), Charset.forName("utf-8")));}}

MessageConsumer2.java

package com.rabbitmq;import java.nio.charset.Charset;import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;/*** @Title消息消费者2* @date 2023/10/8*/
public class MessageConsumer2 implements MessageListener {@Overridepublic void onMessage(Message message) {// 逻辑处理System.out.println("message2------->:" + new String(message.getBody(), Charset.forName("utf-8")));}}

MessageProducer.java

package com.rabbitmq;import javax.annotation.Resource;import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;/*** @Title 消息生产者* @date 2023/10/8*/
@Service
public class MessageProducer {@Resourceprivate AmqpTemplate amqpTemplate;public void sendMessage(String key, Object message){amqpTemplate.convertAndSend(key, message);}}

MessageConstant.java

package com.rabbitmq;/*** @Title 消息队列常量* @date 2023/10/8*/
public class MessageConstant{public static String queueTestKey = "queueTestKey";public static String queueTestKey1 = "queueTestKey1";}

测试调用

比如这个下面在某个类里作为接口调用测试

	@Autowiredprivate MessageProducer messageProducer;@RequestMapping(value = "/testMq")@ResponseBodypublic Result testMq(HttpServletRequest request) throws IOException {messageProducer.sendMessage(MessageConstant.queueTestKey, "登录");messageProducer.sendMessage(MessageConstant.queueTestKey1, "退出");return Result.success("测试成功");}

调用接口后打印结果
在这里插入图片描述
连接结果
在这里插入图片描述
以上即可!

扩展

包括消息手动确认,消息失败重新加入队列处理

消息重发

SpringBoot版可在配置文件中设置,且异常后直接抛出即可

方式一

package com.rabbitmq;import java.nio.charset.Charset;import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;import com.rabbitmq.client.Channel;/*** @Title 消息消费者* @date 2023/10/8*/
public class MessageConsumer2 implements ChannelAwareMessageListener {private int aa = 1;@Overridepublic void onMessage(Message message, Channel channel) throws Exception {try {// 逻辑处理if(aa == 1) {aa = 2;int a = 1/0;}System.out.println("成功处理确认message2------->:" + new String(message.getBody(), Charset.forName("utf-8")));// 消费者ack确认【消息处理成功确认】channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);}catch (Exception e) {System.out.println("失败重新入队message2------->:" + new String(message.getBody(), Charset.forName("utf-8")));// 消费者reject确认【消息失败重新加入队列-重发】channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);}}}

方式二

MessageConstant.java中加入

	/** 重试次数 3 */public static Integer RETRY_COUNT = 3;

消息接收处理类

package com.rabbitmq;import java.nio.charset.Charset;import org.apache.log4j.Logger;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;import com.alibaba.fastjson.JSONObject;
import com.bean.ConsumptionRequest;
import com.rabbitmq.client.Channel;
import com.service.ReceiveDormitoryService;/*** 宿舍mq消息处理* * @author Administrator*/
public class MessageConsumerSuShe implements ChannelAwareMessageListener {private final Logger logger = Logger.getLogger(MessageConsumerSuShe.class);@Autowiredprivate ReceiveDormitoryService service;@Overridepublic void onMessage(Message message, Channel channel) throws Exception {int retryCount = 0; // 重试机制long deliveryTag = message.getMessageProperties().getDeliveryTag();while(retryCount < MessageConstant.RETRY_COUNT) {retryCount ++;try {// 逻辑处理String s = new String(message.getBody(), Charset.forName("utf-8"));ConsumptionRequest bean = JSONObject.parseObject(s, ConsumptionRequest.class);//service.uploadData(bean, bean.getPath());//logger.info("【SUSHE_QUEUE_KEY宿舍队列成功】:" + new String(message.getBody(), Charset.forName("utf-8")));// 消费者ack确认【消息处理成功确认】channel.basicAck(deliveryTag, false);return;}catch (Exception e) {logger.error("【SUSHE_QUEUE_KEY宿舍队列错误,重试"+retryCount+"】:" + new String(message.getBody(), Charset.forName("utf-8")));// 0.5s重试一次Thread.sleep(500);}}// 重试3次后直接处理(这里设置为死信消息)if(retryCount >= MessageConstant.RETRY_COUNT) {channel.basicNack(deliveryTag, false, false);}}}

多部署Tomcat下问题

本人使用单个RabbitMQ服务
测试两个Tomcat服务连接同一个交换机和队列进行发送消息,并没有造成两个Tomcat服务都推送处理这条消息,而是单个Tomcat处理了这条消息
所以未造成多部署下一条消息多服务处理问题

其他
参考类似博客1:https://blog.csdn.net/u012988901/article/details/89499634
参考类似博客2:https://blog.csdn.net/weixin_42654295/article/details/109006276

相关文章:

SSM整合RabbitMQ,Spring4.x整合RabbitMQ

SSM整合RabbitMQ目录 前言版本实现目录参考pom.xml依赖rabbitmq.properties配置文件spring-rabbitmq.xmlspring-mvc.xml或applicationContext.xmlrabbitmq目录下MessageConsumer.javaMessageConsumer2.javaMessageProducer.javaMessageConstant.java 测试调用 扩展消息重发方式…...

【2023研电赛】商业计划书赛道上海市一等奖:基于双矢量优化谐波预测控制的MMC-PET光伏储能系统

该作品参与极术社区组织的2023研电赛作品征集活动&#xff0c;欢迎同学们投稿&#xff0c;获取作品传播推广&#xff0c;并有丰富礼品哦~ 团队介绍 参赛单位&#xff1a;上海理工大学 参赛队伍&#xff1a;Dream explorers 参赛队员&#xff1a;吕哲 李天皓 赵安杰 项目意义…...

minio桶命名规则

一、背景 今天做项目需要上传图片到minio&#xff0c;上传失败&#xff0c;查看错误是桶未创建成功。 minio桶的创建具有自己的命名规则&#xff0c;不符合则无法创建。 二、命名规则 1、存储桶名称的长度必须介于 3&#xff08;最小&#xff09;到 63&#xff08;最大&…...

【教学类-35-04】学号+姓名+班级(中3班)学号字帖(A4竖版2份 竖版长条)

图片展示: 背景需求: 2022年9-2023年1月我去过小3班带班&#xff0c;但是没有在这个班级投放过学具&#xff0c;本周五是我在本学期第一次带中3班&#xff0c;所以提供了一套学号描字帖。先让我把孩子的名字和脸混个眼熟。 之前试过一页两套名字的纸张切割方法有&#xff1a;…...

什么叫AI自动直播?

AI自动直播是一种使用人工智能技术进行自动直播的程序或系统。 它可以自动录制视频&#xff0c;并在直播平台上进行展示&#xff0c;以吸引观众并提高品牌知名度。AI自动直播通常需要使用特定的软件或平台来实现&#xff0c;并且需要具备一定的编程和人工智能知识。 AI自动直…...

LLaMA Adapter和LLaMA Adapter V2

LLaMA Adapter论文地址&#xff1a; https://arxiv.org/pdf/2303.16199.pdf LLaMA Adapter V2论文地址&#xff1a; https://arxiv.org/pdf/2304.15010.pdf LLaMA Adapter效果展示地址&#xff1a; LLaMA Adapter 双语多模态通用模型 为你写诗 - 知乎 LLaMA Adapter GitH…...

高压放大器在软体机器人领域的应用

软体机器人是一种新型机器人技术&#xff0c;与传统的硬体机器人有着很大的不同。软体机器人通常由柔软的材料制成&#xff0c;具有高度的柔韧性和灵活性&#xff0c;并且可以实现多种形状和动作。但是&#xff0c;软体机器人的发展面临很多技术挑战&#xff0c;其中之一就是控…...

《Linux C/C++服务器开发实践》之第4章 TCP服务器编程

《Linux C/C服务器开发实践》之第4章 TCP服务器编程 4.1 套接字的基本概念4.2 网络程序的架构4.3 IP地址的格式转换4.1.c 4.4 套接字的类型4.5 套接字地址4.5.1 通用socket地址4.5.2 专用socket地址4.5.3 获取套接字地址4.2.c 4.6 主机字节序和网络字节序4.3.c 4.7 协议族和地址…...

HCIA---静态路由扩展配置

静态的扩展配置&#xff1a; 1、负载均衡&#xff1a;当访问相同目标&#xff0c;具有多条开销相似路径时&#xff1b;可以让设备将流量拆分后延多条路径同时传输&#xff1b;起到带宽叠加的作用&#xff1b; 2、环回接口-- 创建后&#xff0c;可用于路由器测试TCP/IP协议组件…...

OCP Java17 SE Developers 复习题04

答案 F. Line 5 does not compile. This question is checking to see whether you are paying attention to the types. numFish is an int, and 1 is an int. Therefore, we use numeric addition and get 5. The problem is that we cant store an int in a String variab…...

spark中使用flatmap报错:TypeError: ‘int‘ object is not subscriptable

1、背景描述 菜鸟笔者在运行下面代码时发生了报错&#xff1a; from pyspark import SparkContextsc SparkContext("local", "apple1012")rdd sc.parallelize([[1, 2], 3, [7, 5, 6]])rdd1 rdd.flatMap(lambda x: x) print(rdd1.collect())报错描述如…...

node.js知识系列(5)-每天了解一点

目录 21. RESTful API 设计中的 HTTP 动词22. 中间件链和回调地狱23. Express.js 的 ORM 经验24. 错误处理中间件和 HTTP 状态码25. 事件循环&#xff08;Event Loop&#xff09;在异步编程中的作用26. Node.js 缓存机制27. Node.js 全局对象28. 性能分析和调优经验29. Express…...

Linux服务器(银河麒麟、CentOS 7+、CentOS 7+ 等)修改IP地址

打开终端或控制台&#xff0c;以root或具有sudo权限的用户身份登录。根据你的Linux发行版和网络管理工具的不同&#xff0c;相应的命令可能略有不同。使用以下命令编辑网络配置文件&#xff0c;例如eth0网卡的配置文件&#xff1a; 注意&#xff1a;ifcfg-eth0 可能会有不同的命…...

Mall脚手架总结(四) —— SpringBoot整合RabbitMQ实现超时订单处理

前言 在电商项目中&#xff0c;订单因为某种特殊情况被取消或者超时未支付都是比较常规的用户行为&#xff0c;而实现该功能我们就要借助消息中间件来为我们维护这么一个消息队列。在mall脚手架中选择了RabbitMQ消息中间件&#xff0c;接下来荔枝就会根据功能需求来梳理一下超时…...

python实现图像的直方图均衡化

直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分配图像中的像素值&#xff0c;使得图像的像素值分布更加均匀&#xff0c;增强图像的对比度&#xff0c;从而改善图像的视觉效果。 直方图均衡化的过程如下&#xff1a; 灰度转换&#xff1a;如果图像是彩色…...

哪种烧录单片机的方法合适?

哪种烧录单片机的方法合适&#xff1f; 首先&#xff0c;让我们来探讨一下单片机烧录的方式。虽然单片机烧录程序的具体方法会因为单片机型号、然后很多小伙伴私我想要嵌入式资料&#xff0c;通宵总结整理后&#xff0c;我十年的经验和入门到高级的学习资料&#xff0c;只需一…...

安规电容总结

安规电容 顾名思义&#xff1a;电容即使失效后&#xff0c;也不会漏电或者放电伤人&#xff0c;要符合安全规定 多数高压认证产品都需要。 上图&#xff1a; X电容&#xff1a; Y电容&#xff1a; 区别&#xff1a; 电路示意&#xff1a;...

MyCat分片垂直拆分

场景 在业务系统中 , 涉及以下表结构 , 但是由于用户与订单每天都会产生大量的数据 , 单台服务器的数据 存储及处理能力是有限的 , 可以对数据库表进行拆分 , 原有的数据库表如下。 现在考虑将其进行垂直分库操作&#xff0c;将商品相关的表拆分到一个数据库服务器&#…...

MongoDB bin目录没有mongo.exe命令

MongoDB从6.0版本开始就取消了在Bin目录中加入Compass连接工具&#xff0c;需要大家自行安装。 可以定位到我的文章 链接地址 点击右侧目录的 标题三&#xff1a;MongoDB Compass连接MongoDBMongoDB Compass的安装方法哦~...

Zookeeper分布式一致性协议ZAB源码剖析

文章目录 1、ZAB协议介绍2、消息广播 1、ZAB协议介绍 ZAB 协议全称&#xff1a;Zookeeper Atomic Broadcast&#xff08;Zookeeper 原子广播协议&#xff09;。 Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服务。在解决分布式一致性方面&#xff0c;Zookeeper 并…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...