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 并…...

微软 AR 眼镜新专利:包含热拔插电池
近日,微软在增强现实(AR)领域进行深入的研究,并申请了一项有关于“热插拔电池”的专利。该专利于2023年10月5日发布,描述了一款采用模块化设计的AR眼镜,其热插拔电池放置在镜腿部分,可以直接替代…...

软件TFN 2K的分布式拒绝攻击(DDos)实战详解
写在前头 本人写这篇博客的目的,并不是我想成为黑客或者鼓励大家做损坏任何人安全和利益的事情。因科研需要,我学习软件TFN 2K的分布式拒绝攻击,只是分享自己的学习过程和经历,有助于大家更好的关注到网络安全及网络维护上。 需要…...

计算机网络第四章——网络层(末)
赌书消得泼茶香当时只道是寻常 文章目录 概述:组播机制是让源计算机一次发送的单个分组可以抵达用一个组地址标识的若干目标主机,并被它们正确接收,组播仅应用于UDP 因特网中的IP组播也使用组播组的概念,每个组都有一个特别分配的…...

Newman基本使用
目录 简介 安装 使用 官网 运行 输出测试报告文件 htmlextra 使用 简介 Newman 是 Postman 推出的一个 nodejs 库,直接来说就是 Postman 的json文件可以在命令行执行的插件。 Newman 可以方便地运行和测试集合,并用之构造接口自动化测试和持续集成…...

左值引用右值引用
文章目录 左值和右值什么是左值什么是右值左值引用与右值引用的比较左值引用总结右值引用的总结: 右值引用使用场景和意义左值引用的使用场景左值引用的短板 右值引用和移动语义解决上面的问题不仅仅有移动构造还有移动赋值 右值引用引用左值及其一些更深入的使用场…...

学习开发一个RISC-V上的操作系统(汪辰老师) — 一次RV32I加法指令的反汇编
前言 (1)此系列文章是跟着汪辰老师的RISC-V课程所记录的学习笔记。 (2)该课程相关代码gitee链接; (3)PLCT实验室实习生长期招聘:招聘信息链接 前置知识 RISC-V 汇编指令编码格式 &a…...

IDEA中点击New没有Java Class
解决办法:右键src,也可以是其他文件名,点击Mark Directory as 点击Sources Root即可...

打造炫酷效果:用Java优雅地制作Excel迷你图
摘要:本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 迷你图是一种简洁而有效的数据可视化方式,常用于展示趋势和变化。它通常由一…...

pycharm设置pyuic和pyrcc
pyuic设置 适合任何虚拟环境,直接用虚拟环境的python解决一切。。。 E:\anaconda3\envs\qt5\python.exe-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py$FileDir$pyrcc设置 E:\anaconda3\envs\qt5\python.exe-m PyQt5.pyrcc_main $FileName$ -o…...

OpenCV6-图形绘制
OpenCV6-图形绘制 1.绘制圆形2.绘制直线3.绘制椭圆4.绘制多边形5.文字生成6.demo 1.绘制圆形 void cv::circle(InputOutputArray img, // 需要绘制圆形的图像Point center, // 圆心坐标int radius, // 半径,单位为像素const Scalar& colo…...