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

工作中常用的RabbitMQ实践

目录

1.前置知识

准备工作

2.导入依赖

3.生产者

4.消费者

5.验证

验证Direct

验证Fanout

验证Topic



1.前置知识

rabbitmq有五种工作模式;按照有无交换机分为两大类

无交换机的:简单队列(一对一,单生产单消费)、工作队列(工作队列有轮训分发和公平分发两种模式)

有交换机:发布-订阅、路由模式、主题模式

准备工作

安装rabbitmq,并成功启动

2.导入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

3.生产者

生产端项目结构:
 

逻辑:生产者只对交换机进行生产,至于队列绑定等放在消费端进行执行

BusinessConfig

定义了三个不同类型的交换机

direct类型:(当生产者往该交换机发送消息时,他必须指定固定的routingkey,当routingkey值为空,他也会匹配routingkey为空的队列)

fanout类型:(当生产者往该交换机发送消息时,他所绑定的队列都会收到消息,routingkey即使写了也会忽略,一般为空字符串)

Topic类型:(当生产者往该交换机发送消息时,他并不像direct指定固定的routingkey,可以进行模糊匹配,当该routingkey为空时,他会匹配routingkey为空的队列)

package com.zsp.quartz.queue;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;/*** @Author: ZhangSP* @Date: 2023/12/7  14:05*/
public class BusinessConfig {// 声明direct交换机public static final String EXCHANGE_DIRECT= "exchange_direct_inform";// 声明fanout交换机public static final String EXCHANGE_FANOUT= "exchange_fanout_inform";// 声明topic交换机public static final String EXCHANGE_TOPIC= "exchange_topic_inform";
}

TestProducer

生产消息

package com.zsp.quartz.queue;import com.alibaba.fastjson.JSON;
import com.zsp.quartz.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@SpringBootTest
@RunWith(SpringRunner.class)
public class TestProducer {@AutowiredRabbitTemplate rabbitTemplate;@Testpublic void Producer_topics_springbootTest() {//使用rabbitTemplate发送消息String message = "";User user = new User();user.setName("张三");user.setEmail("anjduahsd");message = JSON.toJSONString(user);// directrabbitTemplate.convertAndSend(BusinessConfig.EXCHANGE_DIRECT,"",message);// fanoutrabbitTemplate.convertAndSend(BusinessConfig.EXCHANGE_FANOUT,"",message);// topicrabbitTemplate.convertAndSend(BusinessConfig.EXCHANGE_TOPIC,"",message);}
}

4.消费者

消费者目录结构:

BusinessConfig内容解析:

①定义交换机类型

②配置交换机与队列的绑定关系

③通过容器工厂声明队列

package com.zsp.consumer.queue;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;import javax.annotation.PostConstruct;/*** @Author: ZhangSP* @Date: 2023/12/7  14:05*/
@Slf4j
@Configuration
public class BusinessConfig {// 声明directpublic static final String EXCHANGE_DIRECT= "exchange_direct_inform";public static final String QUEUE_DIRECT_EMAIL = "queue_direct_inform_email";public static final String QUEUE_DIRECT_SMS = "queue_direct_inform_sms";public void BindDirectEmail(Channel channel) {try {channel.exchangeDeclare(EXCHANGE_DIRECT, BuiltinExchangeType.DIRECT.getType(), true);channel.queueDeclare(QUEUE_DIRECT_EMAIL, true, false, false, null);channel.queueBind(QUEUE_DIRECT_EMAIL, EXCHANGE_DIRECT, "");} catch (Exception e) {log.error("声明Direct->email队列时失败", e);}}public void BindDirectSms(Channel channel) {try {channel.exchangeDeclare(EXCHANGE_DIRECT, BuiltinExchangeType.DIRECT.getType(), true);channel.queueDeclare(QUEUE_DIRECT_SMS, true, false, false, null);channel.queueBind(QUEUE_DIRECT_SMS, EXCHANGE_DIRECT, "123");} catch (Exception e) {log.error("声明Direct->sms失败", e);}}// 声明fanoutpublic static final String EXCHANGE_FANOUT= "exchange_fanout_inform";public static final String QUEUE_FANOUT_EMAIL = "queue_fanout_inform_email";public static final String QUEUE_FANOUT_SMS = "queue_fanout_inform_sms";public void BindFanoutEmail(Channel channel) {try {channel.exchangeDeclare(EXCHANGE_FANOUT, BuiltinExchangeType.FANOUT.getType(), true);channel.queueDeclare(QUEUE_FANOUT_EMAIL, true, false, false, null);channel.queueBind(QUEUE_FANOUT_EMAIL, EXCHANGE_FANOUT, "");} catch (Exception e) {log.error("声明Fanout->email队列时失败", e);}}public void BindFanoutSms(Channel channel) {try {channel.exchangeDeclare(EXCHANGE_FANOUT, BuiltinExchangeType.FANOUT.getType(), true);channel.queueDeclare(QUEUE_FANOUT_SMS, true, false, false, null);channel.queueBind(QUEUE_FANOUT_SMS, EXCHANGE_FANOUT,"");} catch (Exception e) {log.error("声明Fanout->sms失败", e);}}// 声明topicpublic static final String EXCHANGE_TOPIC= "exchange_topic_inform";public static final String QUEUE_TOPIC_EMAIL = "queue_topic_inform_email";public static final String QUEUE_TOPIC_SMS = "queue_topic_inform_sms";public static final String ROUTINGKEY_EMAIL="inform.#.email.#";public static final String ROUTINGKEY_SMS="inform.#.sms.#";public void BindTopicEmail(Channel channel) {try {channel.exchangeDeclare(EXCHANGE_TOPIC, BuiltinExchangeType.TOPIC.getType(),true);channel.queueDeclare(QUEUE_TOPIC_EMAIL, true, false, false, null);channel.queueBind(QUEUE_TOPIC_EMAIL, EXCHANGE_TOPIC, ROUTINGKEY_EMAIL);} catch (Exception e) {log.error("声明Topic->email队列时失败", e);}}public void BindTopicSms(Channel channel) {try {channel.exchangeDeclare(EXCHANGE_TOPIC, BuiltinExchangeType.TOPIC.getType(),true);channel.queueDeclare(QUEUE_TOPIC_SMS, true, false, false, null);channel.queueBind(QUEUE_TOPIC_SMS, EXCHANGE_TOPIC,"");} catch (Exception e) {log.error("声明Topic->sms失败", e);}}// 声明队列@Autowired@Qualifier(value = "zspConnectionFactory")private ConnectionFactory connectionFactory;@PostConstructpublic void shengmingQueue() {try {Connection connection = connectionFactory.createConnection();Channel channel = connection.createChannel(false);BindDirectEmail(channel);BindDirectSms(channel);BindFanoutEmail(channel);BindFanoutSms(channel);BindTopicEmail(channel);BindTopicSms(channel);} catch (Exception e) {log.error("业务实例声明绑定队列报错:",e);}}
}

RabbitFactory内容解析:

①创建自定义连接工厂

②通过@Qualifier准确注入连接工厂,创建个性化容器工厂

package com.zsp.consumer.queue;import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableRabbit
public class RabbitFactory {@Bean("zspConnectionFactory")public ConnectionFactory connectionFactory() {CachingConnectionFactory connectionFactory = new CachingConnectionFactory();// 设置RabbitMQ的连接信息,如主机名、端口号、用户名和密码等connectionFactory.setHost("localhost");connectionFactory.setPort(5672);connectionFactory.setUsername("root");connectionFactory.setPassword("root");return connectionFactory;}@Bean("rabbitListenerContainerFactory")public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(@Qualifier("zspConnectionFactory") ConnectionFactory connectionFactory) {SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setConcurrentConsumers(5);factory.setMaxConcurrentConsumers(10);return factory;}
}

ReceiveHandler内容解析:

监听绑定的队列消息

package com.zsp.consumer.queue;import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class ReceiveHandler {//监听自定义的Direct队列@RabbitListener(queues = BusinessConfig.QUEUE_DIRECT_SMS, containerFactory = "rabbitListenerContainerFactory")public void directSMS(String msg, Message message, Channel channel) {JSONObject jsonObject = JSONObject.parseObject(msg);System.out.println("Direct队列->sms队列" + jsonObject);}@RabbitListener(queues = BusinessConfig.QUEUE_DIRECT_EMAIL, containerFactory = "rabbitListenerContainerFactory")public void directEmail(String msg, Message message, Channel channel) {JSONObject jsonObject = JSONObject.parseObject(msg);System.out.println("Direct队列->email队列" + jsonObject);}//监听自定义的Fanout队列@RabbitListener(queues = BusinessConfig.QUEUE_FANOUT_SMS, containerFactory = "rabbitListenerContainerFactory")public void FanoutSMS(String msg, Message message, Channel channel) {JSONObject jsonObject = JSONObject.parseObject(msg);System.out.println("Fanout队列->sms队列" + jsonObject);}@RabbitListener(queues = BusinessConfig.QUEUE_FANOUT_EMAIL, containerFactory = "rabbitListenerContainerFactory")public void FanoutEmail(String msg, Message message, Channel channel) {JSONObject jsonObject = JSONObject.parseObject(msg);System.out.println("Fanout队列->email队列" + jsonObject);}//监听自定义的Topic队列@RabbitListener(queues = BusinessConfig.QUEUE_TOPIC_SMS, containerFactory = "rabbitListenerContainerFactory")public void TopicSMS(String msg, Message message, Channel channel) {JSONObject jsonObject = JSONObject.parseObject(msg);System.out.println("Topic队列->sms队列" + jsonObject);}@RabbitListener(queues = BusinessConfig.QUEUE_TOPIC_EMAIL, containerFactory = "rabbitListenerContainerFactory")public void TopicEmail(String msg, Message message, Channel channel) {JSONObject jsonObject = JSONObject.parseObject(msg);System.out.println("Topic队列->email队列" + jsonObject);}
}

5.验证

先启动消费者端,然后执行TestProducer

验证Direct

1.向routingkey为空的队列发消息

我们在消费者端配置了routingkey为空的队列,叫做 QUEUE_DIRECT_EMAIL

因此会打印出下面这条记录

2.向routingkey为123的队列发消息

我们在消费者端配置了routingkey为123的队列,叫做 QUEUE_DIRECT_SMS

因此会打出下面这条记录

验证Fanout

谁跟我绑定了,我都发

验证Topic

模糊匹配routingkey

匹配sms队列

会把下面这个打印出来

需要注意的是如果我们没有自定义容器工厂的话,这个containerFactory可以不写
简单理解就是实例,也就是rabbitmq服务地址是在哪里,实例包括了域名、端口、账号、密码等。

相关文章:

工作中常用的RabbitMQ实践

目录 1.前置知识 准备工作 2.导入依赖 3.生产者 4.消费者 5.验证 验证Direct 验证Fanout 验证Topic 1.前置知识 rabbitmq有五种工作模式&#xff1b;按照有无交换机分为两大类 无交换机的&#xff1a;简单队列(一对一,单生产单消费)、工作队列(工作队列有轮训分发和公…...

程序员常用英文单词

英语对于程序员来说多么重要应该无需过多解释了&#xff0c;把近期在网上收集到的分享到这里供大家学习交流。 PS&#xff1a;感谢原作者的收集&#xff0c;谢谢。 A abstract 抽象的 abstract base class (ABC) 抽象基类abstract class 抽象类 abstraction 抽象、抽象物、抽象…...

QStringListModel 是 Qt 框架中用于在模型-视图(Model-View)架构中展示字符串列表的类

QStringListModel 是 Qt 框架中用于在模型-视图&#xff08;Model-View&#xff09;架构中展示字符串列表的类。 QStringListModel 继承自 QAbstractListModel&#xff0c;是一个基于字符串列表的数据模型。它提供了一种方便的方式来将字符串列表作为数据源&#xff0c;供各种…...

vue使用echarts显示中国地图

项目引入echarts以后&#xff0c;在页面创建canvas标签 引入一个公共js文件&#xff08;下面这段代码就是china.js文件&#xff09; (function (root, factory) {if (typeof define function && define.amd) {// AMD. Register as an anonymous module.define([ex…...

ATM的转账

【 1 】明确我们要实现的功能 # 用户功能菜单 # 1.注册 # 2.登陆 # 3.取款 # 4.转账 # 5.充值余额 # 6.查看流水 # 7.查看银行信息(查看自己…...

在Windows 10或11中,复制和粘贴不起作用,不一定是键盘的问题

以下建议将帮助你解决复制和粘贴无法正常工作的问题。 以下提示主要适用于Windows 10和Windows 11,但也可能解决旧版本Windows上的复制和粘贴问题。 为什么我的复制粘贴不起作用 复制和粘贴不起作用的问题可能以以下方式之一出现。 其他正在运行的应用程序或进程可能会使用…...

git 使用记录

远程仓库为空初始化 初始化本地仓库 git init 在本地仓库书写代码&#xff08;这里可以编辑一个文本文件做测试&#xff0c;如hello.txt&#xff09; 5&#xff09;执行&#xff1a;git add 要让git管理的文件&#xff08;git add hello.txt&#xff09;>执行完此操作将我…...

支持大模型训练的计算机系统

摘要&#xff1a; 训练数据决定了基础大模型可用的理论信息&#xff0c;模型架构和训练目标决定了可以提取多少信息&#xff0c;计算机系统决定了实际可实现的内容。在数据和模型大小方面&#xff0c;系统是扩展的关键瓶颈&#xff0c;这两者似乎都可以可靠地跟踪能力的改进。在…...

SAP ABAP-AVL-OO方法中的ALV的如何自己添加按钮及其响应

ABAP-AVL-OO方法中的ALV的如何自己添加按钮及其响应 SAP在做报表开发中&#xff0c;不同公司对报表的风格往往各异&#xff0c;为此经常在使用OO方法做ALV报表中需要去掉自带的工具栏而自行添加一些工具按钮&#xff0c;下面将简单介绍一下添加按钮及如何响应的实现方法&#…...

uniapp移动端悬浮按钮(吸附边缘)

Uniapp移动端悬浮按钮可以通过CSS实现吸附边缘的效果。具体实现步骤如下&#xff1a; html&#xff1a; <movable-area class"movable-area"><movable-view class"movable-view" :position"position" :x"x" :y"y"…...

【成功】Linux安装Mysql8并设置远程连接

今天在新搞来的阿里云的服务器里安装MySQL8&#xff0c;记录一下过程&#xff1a; 这是MySQL的官网和下载地址&#xff1a;MySQL :: Download MySQL Community Server (Archived Versions) 1. 先进入安装目录 cd /usr/local 2. 安装 wget https://downloads.mysql.com/arch…...

高效纯化树脂A-2313 CPR

在化工、制药等行业中&#xff0c;对colorful chemicals的纯化一直是挑战。本文将为您介绍一款具有卓越性能的强碱性阴离子交换树脂——Tulsion A-2313 CPR。通过分析其特性和应用&#xff0c;展示其在colorful chemicals纯化领域的优势。 一、Tulsion A-2313 CPR离子交换树脂的…...

uni-app实现安卓原生态调用身份证阅读器读卡库读身份证和社保卡、银行卡、IC卡等功能

DONSEE系列多功能读写器Android Uniapp API接口规范V1.0.0 本项目Uniapp调用了身份证读卡器的库文件&#xff1a;DonseeDeviceLib-debug.aar&#xff0c;该库放到nativeplugins\donsee-card\android&#xff0c;然后会自动加载。SDK会自动检查是否拥有USB设备权限&#xff0c;…...

【QT】QComboBox和QPlainTextEdit基本介绍和应用示例

目录 1.QComboBox 1.1 QComboBox概述 1.2 QComboBox信号 1.3 QComboBox常用功能 1.4 QComboBox添加简单项 1.6 QComboBox列表项的访问 2.QPlainTextEdit 2.1 QPlainTextEdit概述 2.2 QPlainTextEdit的基本属性 2.3 QPlainTextEdit的公共函数 2.4 QPlainTextEdit的公…...

Path的使用-path绘制折线的时候带上圆角

场景&#xff1a; 使用antv-g6 自定义边的时候&#xff0c;绘制折线&#xff0c;此时都是直角&#xff0c;需要加圆角&#xff0c;没找到属性&#xff0c;自己绘制&#xff1a; 最后使用了A&#xff08;elliptical Arc&#xff09;弧形 A命令用于画弧形。 A rx ry x-axis-r…...

Go Fyne 入门

Fyne是一个用于创建原生应用程序的UI工具包&#xff0c;它简单易用&#xff0c;并且支持跨平台。以下是一个简单的Fyne教程&#xff0c;帮助你入门&#xff1a; 1. 安装Fyne 首先&#xff0c;确保你已经安装了Go语言。然后&#xff0c;在终端中运行以下命令来安装Fyne&#x…...

如何为游戏角色3D模型设置纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时&#xff0c;有几种不同的风格&#xf…...

2024 年 SEO 现状

搜索引擎优化&#xff08;SEO&#xff09;一直以来都是网络知名度和成功的基石。随着我们踏上 2024 年的征程&#xff0c;SEO领域正在经历重大变革&#xff0c;有些变革已经开始&#xff0c;这对企业、创作者和营销人员来说既是挑战也是机遇。 语音搜索 语音搜索曾是一个未来…...

Mac虚拟机CrossOver23破解版下载和许可证下载

CrossOver Mac Mac 和 Windows 系统之间的兼容工具。使 Mac 操作系统的用户可以运行 Windows 系统的应用&#xff0c;从办公软件、实用工具、游戏到设计软件&#xff0c; 您都可以在 Mac 程序和 Windows 程序之间随意切换。 系统要求 运行macOS的基于Intel或Apple Silicon 的…...

宝藏级实用工具,制作电子书轻而易举

电子书是一种数字化的书籍形式&#xff0c;可以通过互联网进行传播和分享。相比于传统的纸质书籍&#xff0c;电子书具有便携、环保、易于分享等优点。如今&#xff0c;越来越多的人开始选择阅读电子书&#xff0c;它已经成为了一种流行的阅读方式。 那么&#xff0c;如何制作电…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...