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研电赛作品征集活动,欢迎同学们投稿,获取作品传播推广,并有丰富礼品哦~ 团队介绍 参赛单位:上海理工大学 参赛队伍:Dream explorers 参赛队员:吕哲 李天皓 赵安杰 项目意义…...
minio桶命名规则
一、背景 今天做项目需要上传图片到minio,上传失败,查看错误是桶未创建成功。 minio桶的创建具有自己的命名规则,不符合则无法创建。 二、命名规则 1、存储桶名称的长度必须介于 3(最小)到 63(最大&…...
【教学类-35-04】学号+姓名+班级(中3班)学号字帖(A4竖版2份 竖版长条)
图片展示: 背景需求: 2022年9-2023年1月我去过小3班带班,但是没有在这个班级投放过学具,本周五是我在本学期第一次带中3班,所以提供了一套学号描字帖。先让我把孩子的名字和脸混个眼熟。 之前试过一页两套名字的纸张切割方法有:…...
什么叫AI自动直播?
AI自动直播是一种使用人工智能技术进行自动直播的程序或系统。 它可以自动录制视频,并在直播平台上进行展示,以吸引观众并提高品牌知名度。AI自动直播通常需要使用特定的软件或平台来实现,并且需要具备一定的编程和人工智能知识。 AI自动直…...
LLaMA Adapter和LLaMA Adapter V2
LLaMA Adapter论文地址: https://arxiv.org/pdf/2303.16199.pdf LLaMA Adapter V2论文地址: https://arxiv.org/pdf/2304.15010.pdf LLaMA Adapter效果展示地址: LLaMA Adapter 双语多模态通用模型 为你写诗 - 知乎 LLaMA Adapter GitH…...
高压放大器在软体机器人领域的应用
软体机器人是一种新型机器人技术,与传统的硬体机器人有着很大的不同。软体机器人通常由柔软的材料制成,具有高度的柔韧性和灵活性,并且可以实现多种形状和动作。但是,软体机器人的发展面临很多技术挑战,其中之一就是控…...
《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---静态路由扩展配置
静态的扩展配置: 1、负载均衡:当访问相同目标,具有多条开销相似路径时;可以让设备将流量拆分后延多条路径同时传输;起到带宽叠加的作用; 2、环回接口-- 创建后,可用于路由器测试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、背景描述 菜鸟笔者在运行下面代码时发生了报错: 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. 事件循环(Event Loop)在异步编程中的作用26. Node.js 缓存机制27. Node.js 全局对象28. 性能分析和调优经验29. Express…...
Linux服务器(银河麒麟、CentOS 7+、CentOS 7+ 等)修改IP地址
打开终端或控制台,以root或具有sudo权限的用户身份登录。根据你的Linux发行版和网络管理工具的不同,相应的命令可能略有不同。使用以下命令编辑网络配置文件,例如eth0网卡的配置文件: 注意:ifcfg-eth0 可能会有不同的命…...
Mall脚手架总结(四) —— SpringBoot整合RabbitMQ实现超时订单处理
前言 在电商项目中,订单因为某种特殊情况被取消或者超时未支付都是比较常规的用户行为,而实现该功能我们就要借助消息中间件来为我们维护这么一个消息队列。在mall脚手架中选择了RabbitMQ消息中间件,接下来荔枝就会根据功能需求来梳理一下超时…...
python实现图像的直方图均衡化
直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分配图像中的像素值,使得图像的像素值分布更加均匀,增强图像的对比度,从而改善图像的视觉效果。 直方图均衡化的过程如下: 灰度转换:如果图像是彩色…...
哪种烧录单片机的方法合适?
哪种烧录单片机的方法合适? 首先,让我们来探讨一下单片机烧录的方式。虽然单片机烧录程序的具体方法会因为单片机型号、然后很多小伙伴私我想要嵌入式资料,通宵总结整理后,我十年的经验和入门到高级的学习资料,只需一…...
安规电容总结
安规电容 顾名思义:电容即使失效后,也不会漏电或者放电伤人,要符合安全规定 多数高压认证产品都需要。 上图: X电容: Y电容: 区别: 电路示意:...
MyCat分片垂直拆分
场景 在业务系统中 , 涉及以下表结构 , 但是由于用户与订单每天都会产生大量的数据 , 单台服务器的数据 存储及处理能力是有限的 , 可以对数据库表进行拆分 , 原有的数据库表如下。 现在考虑将其进行垂直分库操作,将商品相关的表拆分到一个数据库服务器&#…...
MongoDB bin目录没有mongo.exe命令
MongoDB从6.0版本开始就取消了在Bin目录中加入Compass连接工具,需要大家自行安装。 可以定位到我的文章 链接地址 点击右侧目录的 标题三:MongoDB Compass连接MongoDBMongoDB Compass的安装方法哦~...
Zookeeper分布式一致性协议ZAB源码剖析
文章目录 1、ZAB协议介绍2、消息广播 1、ZAB协议介绍 ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。 Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服务。在解决分布式一致性方面,Zookeeper 并…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: 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 解决方案&…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
