引言:

  • 本文总字数:约 9200 字
  • 预计阅读时间:38 分钟

为什么 RabbitMQ 是消息中间件的优选?

在分布式系统架构中,消息中间件扮演着 "交通枢纽" 的角色,负责协调各个服务之间的通信。目前主流的消息中间件有 RabbitMQ、Kafka 和 RocketMQ,它们各具特色:

  • Kafka:高吞吐量,适合大数据日志处理,但消息可靠性和灵活性较弱
  • RocketMQ:阿里开源,兼顾吞吐量和可靠性,适合复杂业务场景
  • RabbitMQ:基于 AMQP 协议,灵活性高,插件丰富,社区活跃,学习曲线友好

根据 RabbitMQ 官方数据,它在全球财富 500 强公司中被广泛采用,能轻松处理每秒数万条消息,且提供了近乎完美的消息可靠性保证。其独特的交换机模型和灵活的路由规则,使其成为业务复杂多变场景的理想选择。

本文将带你从零开始,全面掌握 SpringBoot 与 RabbitMQ 的整合方案,从基础配置到高级特性,从代码实现到性能调优,让你既能理解底层原理,又能解决实际开发中的各种问题。

一、RabbitMQ 核心概念与架构

1.1 核心概念解析

RabbitMQ 基于 AMQP(Advanced Message Queuing Protocol)协议实现,核心概念包括:

  • Producer:消息生产者,负责发送消息到 RabbitMQ 服务器
  • Consumer:消息消费者,负责从 RabbitMQ 服务器接收并处理消息
  • Broker:RabbitMQ 服务器实例,负责消息的存储和转发
  • Exchange:交换机,接收生产者发送的消息,并根据路由规则将消息路由到队列
  • Queue:消息队列,存储消息直到被消费者消费
  • Binding:绑定,定义交换机和队列之间的关联关系,包含路由规则
  • Routing Key:路由键,生产者发送消息时指定,用于交换机路由消息
  • Virtual Host:虚拟主机,提供资源隔离,不同虚拟主机之间的资源相互独立

1.2 交换机类型

RabbitMQ 提供了四种主要的交换机类型,适用于不同的路由场景:

  1. Direct Exchange:直接交换机,根据路由键精确匹配进行路由
  2. Topic Exchange:主题交换机,支持通配符匹配路由键(*匹配一个单词,#匹配多个单词)
  3. Fanout Exchange:扇形交换机,忽略路由键,将消息广播到所有绑定的队列
  4. Headers Exchange:头交换机,根据消息头信息而不是路由键进行路由

1.3 架构原理

RabbitMQ 的整体架构如图所示:

消息流转流程:

  1. 生产者将消息发送到交换机,并指定路由键
  2. 交换机根据自身类型和绑定规则,将消息路由到一个或多个队列
  3. 消费者从队列中获取消息并处理
  4. 消息被消费后,默认从队列中删除

根据 RabbitMQ 官方文档(RabbitMQ Documentation | RabbitMQ),这种架构设计使得 RabbitMQ 具有极高的灵活性,可以通过不同的交换机和绑定组合,实现复杂的消息路由策略。

二、环境搭建

2.1 安装 RabbitMQ

我们采用最新稳定版 RabbitMQ 3.13.0 进行安装,步骤如下:

  1. 安装 Erlang(RabbitMQ 依赖 Erlang 环境):
# 对于Ubuntu/Debian
sudo apt-get update
sudo apt-get install erlang# 对于CentOS/RHEL
sudo yum install erlang
  1. 安装 RabbitMQ:
# 对于Ubuntu/Debian
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.0/rabbitmq-server_3.13.0-1_all.deb
sudo dpkg -i rabbitmq-server_3.13.0-1_all.deb# 对于CentOS/RHEL
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.0/rabbitmq-server-3.13.0-1.el8.noarch.rpm
sudo rpm -ivh rabbitmq-server-3.13.0-1.el8.noarch.rpm
  1. 启动 RabbitMQ 服务:
sudo systemctl start rabbitmq-server
sudo systemctl enable rabbitmq-server
  1. 启用管理插件:
sudo rabbitmq-plugins enable rabbitmq_management
  1. 创建管理员用户:
sudo rabbitmqctl add_user admin password
sudo rabbitmqctl set_user_tags admin administrator
sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
  1. 访问管理界面:
    打开浏览器访问http://localhost:15672,使用创建的 admin 用户登录。

2.2 安装 Docker 方式(推荐)

使用 Docker 安装 RabbitMQ 更加简单快捷:

# 拉取镜像
docker pull rabbitmq:3.13.0-management# 启动容器
docker run -d --name rabbitmq \-p 5672:5672 \-p 15672:15672 \-e RABBITMQ_DEFAULT_USER=admin \-e RABBITMQ_DEFAULT_PASS=password \rabbitmq:3.13.0-management

三、SpringBoot 集成 RabbitMQ 基础

3.1 创建项目并添加依赖

我们使用 SpringBoot 3.2.0(最新稳定版)来创建项目,首先在 pom.xml 中添加必要的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0</version><relativePath/></parent><groupId>com.jam</groupId><artifactId>springboot-rabbitmq-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-rabbitmq-demo</name><description>SpringBoot集成RabbitMQ示例项目</description><properties><java.version>17</java.version><lombok.version>1.18.30</lombok.version><commons-lang3.version>3.14.0</commons-lang3.version><mybatis-plus.version>3.5.5</mybatis-plus.version><mysql-connector.version>8.2.0</mysql-connector.version><springdoc.version>2.1.0</springdoc.version></properties><dependencies><!-- SpringBoot核心依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- RabbitMQ依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version><scope>provided</scope></dependency><!-- 工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons-lang3.version}</version></dependency><!-- MyBatis-Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!-- MySQL驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql-connector.version}</version><scope>runtime</scope></dependency><!-- Swagger3 --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>${springdoc.version}</version></dependency><!-- 测试依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>
</project>

3.2 配置 RabbitMQ

在 application.yml 中添加 RabbitMQ 的配置:

spring:application:name: springboot-rabbitmq-demodatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/rabbitmq_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: rootrabbitmq:host: localhostport: 5672username: adminpassword: passwordvirtual-host: /# 连接超时时间,单位毫秒connection-timeout: 10000# 生产者配置publisher-confirm-type: correlated # 开启发布确认机制publisher-returns: true # 开启发布返回机制# 消费者配置listener:simple:# 并发消费者数量concurrency: 5# 最大并发消费者数量max-concurrency: 10# 每次从队列中拉取的消息数量prefetch: 1# 消息确认模式:manual-手动确认,auto-自动确认acknowledge-mode: manual# 消费失败时是否重试retry:enabled: true# 初始重试间隔时间initial-interval: 1000# 重试最大间隔时间max-interval: 10000# 重试乘数multiplier: 2# 最大重试次数max-attempts: 3mybatis-plus:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.jam.entityconfiguration:map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImplspringdoc:api-docs:path: /api-docsswagger-ui:path: /swagger-ui.htmloperationsSorter: methodserver:port: 8081

3.3 创建 RabbitMQ 配置类

创建配置类,定义交换机、队列和绑定关系:

package com.jam.config;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** RabbitMQ配置类* 定义交换机、队列和绑定关系** @author 果酱*/
@Configuration
public class RabbitMQConfig {/*** 直接交换机名称*/public static final String DIRECT_EXCHANGE = "direct_exchange";/*** 主题交换机名称*/public static final String TOPIC_EXCHANGE = "topic_exchange";/*** 扇形交换机名称*/public static final String FANOUT_EXCHANGE = "fanout_exchange";/*** 头交换机名称*/public static final String HEADERS_EXCHANGE = "headers_exchange";/*** 直接队列1名称*/public static final String DIRECT_QUEUE_1 = "direct_queue_1";/*** 直接队列2名称*/public static final String DIRECT_QUEUE_2 = "direct_queue_2";/*** 主题队列1名称*/public static final String TOPIC_QUEUE_1 = "topic_queue_1";/*** 主题队列2名称*/public static final String TOPIC_QUEUE_2 = "topic_queue_2";/*** 扇形队列1名称*/public static final String FANOUT_QUEUE_1 = "fanout_queue_1";/*** 扇形队列2名称*/public static final String FANOUT_QUEUE_2 = "fanout_queue_2";/*** 头队列名称*/public static final String HEADERS_QUEUE = "headers_queue";/*** 死信交换机名称*/public static final String DEAD_LETTER_EXCHANGE = "dead_letter_exchange";/*** 死信队列名称*/public static final String DEAD_LETTER_QUEUE = "dead_letter_queue";/*** 延迟队列名称*/public static final String DELAY_QUEUE = "delay_queue";// ==================== 交换机 ====================/*** 创建直接交换机** @return 直接交换机*/@Beanpublic DirectExchange directExchange() {// durable: 是否持久化// autoDelete: 是否自动删除(当没有绑定关系时)// arguments: 交换机的其他属性return new DirectExchange(DIRECT_EXCHANGE, true, false);}/*** 创建主题交换机** @return 主题交换机*/@Beanpublic TopicExchange topicExchange() {return new TopicExchange(TOPIC_EXCHANGE, true, false);}/*** 创建扇形交换机** @return 扇形交换机*/@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange(FANOUT_EXCHANGE, true, false);}/*** 创建头交换机** @return 头交换机*/@Beanpublic HeadersExchange headersExchange() {return new HeadersExchange(HEADERS_EXCHANGE, true, false);}/*** 创建死信交换机** @return 死信交换机*/@Beanpublic DirectExchange deadLetterExchange() {return new DirectExchange(DEAD_LETTER_EXCHANGE, true, false);}// ==================== 队列 ====================/*** 创建直接队列1** @return 直接队列1*/@Beanpublic Queue directQueue1() {// durable: 是否持久化// exclusive: 是否排他(仅当前连接可见,连接关闭后删除)// autoDelete: 是否自动删除(当没有消费者时)// arguments: 队列的其他属性return QueueBuilder.durable(DIRECT_QUEUE_1).build();}/*** 创建直接队列2** @return 直接队列2*/@Beanpublic Queue directQueue2() {return QueueBuilder.durable(DIRECT_QUEUE_2).build();}/*** 创建主题队列1** @return 主题队列1*/@Beanpublic Queue topicQueue1() {return QueueBuilder.durable(TOPIC_QUEUE_1).build();}/*** 创建主题队列2** @return 主题队列2*/@Beanpublic Queue topicQueue2() {return QueueBuilder.durable(TOPIC_QUEUE_2).build();}/*** 创建扇形队列1** @return 扇形队列1*/@Beanpublic Queue fanoutQueue1() {return QueueBuilder.durable(FANOUT_QUEUE_1).build();}/*** 创建扇形队列2** @return 扇形队列2*/@Beanpublic Queue fanoutQueue2() {return QueueBuilder.durable(FANOUT_QUEUE_2).build();}/*** 创建头队列** @return 头队列*/@Beanpublic Queue headersQueue() {return QueueBuilder.durable(HEADERS_QUEUE).build();}/*** 创建死信队列** @return 死信队列*/@Beanpublic Queue deadLetterQueue() {return QueueBuilder.durable(DEAD_LETTER_QUEUE).build();}/*** 创建延迟队列* 设置死信交换机和死信路由键** @return 延迟队列*/@Beanpublic Queue delayQueue() {return QueueBuilder.durable(DELAY_QUEUE)// 设置死信交换机.withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)// 设置死信路由键.withArgument("x-dead-letter-routing-key", "dead.letter.key").build();}// ==================== 绑定 ====================/*** 绑定直接队列1到直接交换机** @return 绑定关系*/@Beanpublic Binding directBinding1() {// 将directQueue1绑定到directExchange,路由键为"direct.key1"return BindingBuilder.bind(directQueue1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95482.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95482.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/95482.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nestjs 发起请求 axios

1、下载npm i --save nestjs/axios axios2、全局配置import { HttpModule } from nestjs/axios;Global() Module({imports: [HttpModule.registerAsync({inject: [ConfigService],useFactory: async (configService: ConfigService) > {return {timeout: configService.get(…

将 Logits 得分转换为概率,如何计算

场景&#xff1a;动物识别&#xff0c;输入一张28*28的图像&#xff0c;模型输出属于 猫、狗、鸟 哪个类型。需求&#xff1a;假设模型 ​​Logits&#xff08;模型在每个类别的置信度得分&#xff09; 输出为​​&#xff1a;[猫: 3.2, 狗: 1.5, 鸟: -0.8]。计算 ​​Softmax …

【Qt】bug排查笔记——QMetaObject::invokeMethod: No such method

问题如题目所示&#xff1a;QMetaObject::invokeMethod: No such method xxxx&#xff0c;在网上好一顿查&#xff0c;又将查到的资料喂给了 Ai&#xff0c;才最终将问题解决&#xff0c;特此记录下。 一、问题背景 在做公司项目时&#xff0c;使用了插件的方式开发。主程序加载…

Spring Boot手写10万敏感词检查程序

使用Spring Boot手写10万敏感词检查程序 本文将介绍如何使用Spring Boot构建一个高效的敏感词检查系统,能够处理多达10万个敏感词的检测需求。我们将使用DFA(Deterministic Finite Automaton)算法来实现高效匹配,并提供RESTful API接口。 实现步骤 1. 创建Spring Boot项…

零构建的快感!dagger.js 与 React Hooks 实现对比,谁更优雅?

“Add Tags” 技术方案并行对比&#xff1a;React Hooks vs dagger.js&#xff08;含核心 JS 代码&#xff09; 源码&#xff1a; React Hooks&#xff1a;https://codepen.io/prvnbist/pen/jJzROe?editors1010dagger.js&#xff1a;https://codepen.io/dagger8224/pen/ZErjzw…

矩池云中LLaMA- Factory多机多卡训练

LLaMA Factory 是一款开源低代码大模型微调框架&#xff0c;集成了业界最广泛使用的微调技术&#xff0c;支持通过 Web UI 界面零代码微调大模型&#xff0c;目前已经成为开源社区内最受欢迎的微调框架之一。但是在矩池云上如何使用LLaMA-Factory多机多卡训练模型呢&#xff1f…

Nginx的反向代理与正向代理及其location的配置说明

一、Nginx中location匹配优先级Nginx中location匹配优先级location支持各种匹配规则&#xff0c;在多个匹配规则下&#xff0c;Nginx对location的处理是有优先级的&#xff0c;优先级高的规则会优先进行处理&#xff1b;而优先级低的规则可能会最后处理或者不进行处理。注意&am…

神经网络正则化三重奏:Weight Decay, Dropout, 和LayerNorm

正则化是机器学习中防止模型过拟合、提升泛化能力的核心技术。Weight Decay、Dropout和LayerNorm是三种最常用的方法&#xff0c;但它们的工作原理和首要目标截然不同。下面的流程图揭示了它们的核心区别与联系&#xff1a; #mermaid-svg-vymek6mFvvfxcWiM {font-family:"…

两台电脑通过网线直连共享数据,设置正确,却互相ping不通的解决方法

因为某些原因&#xff0c;需要两台电脑互传资源&#xff0c;但是某台电脑可能无法连接外网。如果手头有根网线&#xff0c;很容易想到通过一根网线连接两台电脑互传数据。 这里先说一下基本的设置&#xff1a; 两台电脑最好都关闭防火墙&#xff1b;两台电脑都打开专用网络和公…

面试新纪元:无声胜有声,让AI成为你颈上的智慧伙伴

面试&#xff0c;无论是对于面试官还是求职者&#xff0c;都像一场无声的战争。 一方要精准识人&#xff0c;一方要完美自荐&#xff1b;一方怕问不到点子上&#xff0c;一方怕答不到心坎里。 紧张、遗忘、表达失误、准备不足……这些问题几乎每个人都经历过。 有没有一种方…

qt-C++笔记之QtDesigner-Creator按钮图标与样式

qt-C笔记之QtDesigner-Creator按钮图标与样式 整理&#xff1a;如何用 .qrc 管理资源、在 Designer/Creator 中为 QPushButton 设置图标&#xff08;资源或系统主题&#xff09;&#xff0c;以及用样式表调整文字样式。涵盖 C/Qt 与 PySide/PyQt&#xff1b;Linux 桌面优先&am…

maven 常用指令

Maven 是 Java 项目构建和依赖管理的得力助手。这里为你总结了一些常用指令&#xff0c;希望能帮你提升开发效率。下面这个表格汇总了 Maven 最核心和常用的一些命令&#xff1a;命令主要功能典型使用场景mvn clean清理项目&#xff0c;删除 target 目录及其所有编译输出文件。…

# pdf.js完全指南:构建现代Web PDF查看与解析解决方案

在当今Web开发中&#xff0c;实现高质量的PDF查看功能一直是前端开发者面临的挑战之一。作为最受欢迎的JavaScript PDF库&#xff0c;pdf.js已经成为解决这一问题的行业标准。由Mozilla开发并维护的pdf.js项目&#xff0c;通过纯JavaScript实现PDF解析与渲染&#xff0c;彻底改…

高效对象属性复制工具

日常编程中&#xff0c;经常会碰到对象属性复制的场景&#xff0c;比如 VO、DTO、PO、VO 等之间的转换&#xff0c;关于什么是VO、DTO、PO、VO 等可以看上篇文章&#xff0c;VO、DTO、PO、VO 等对象具体有哪些方式可以使用呢&#xff1f; set/get 方式 性能最好的方式&#x…

大疆图传技术参数对比 你了解多少?

无人机是现代航空技术与智能控制技术结合的产物&#xff0c;已从军事领域广泛渗透至民用场景&#xff0c;成为推动各行业效率升级的关键工具。无人机的全称为 “无人驾驶航空器&#xff08;Unmanned Aerial Vehicle&#xff0c;简称 UAV&#xff09;”&#xff0c;简言之&#…

Redis 缓存热身(Cache Warm-up):原理、方案与实践

在 Redis 缓存架构中&#xff0c;“缓存热身”是指在系统正式提供服务前&#xff08;如重启、扩容后&#xff09;&#xff0c;主动将热点数据加载到 Redis 中的操作。其核心目标是避免**缓存穿透**&#xff08;请求直达数据库&#xff09;和**缓存雪崩**&#xff08;大量请求同…

基于SpringBoot的大学生就业招聘系统

1. 在线演示&#xff1a; 后台&#xff1a;http://springbootiv1oo.xiaobias.com/springbootiv1oo/admin/dist/index.html 前台&#xff1a;http://springbootiv1oo.xiaobias.com/springbootiv1oo/front/index.html 管理员&#xff1a;abo/abo 用户&#xff1a;用户1/123456、…

Java反序列化漏洞揭秘:从原理到攻击实战

一、背景 熟悉接口开发的同学一定知道&#xff0c;能将数据对象很轻松的实现多平台之间的通信、对象持久化存储&#xff0c;序列化和反序列化是一种非常有效的手段&#xff0c;例如如下应用场景&#xff0c;对象必须 100% 实现序列化。 DUBBO&#xff1a;对象传输必须要实现序…

Time-MOE 音频序列分类任务

prompt 我准备做语音疾病分类任务。语音音频是 WAV 格式的音频&#xff0c;基本上分为两类&#xff0c;分别是疾病类和非疾病类。也有少数数据集是多分类&#xff0c;现在我找到了26个数据集&#xff0c;我准备我已经在 MLP CNN 上面测试了它们的基准&#xff0c;下面我找到了一…

[嵌入式embed][Qt]Qt5.12+Opencv4.x+Cmake4.x_测试Qt编译的opencv4.x的库

[嵌入式embed][Qt]Qt5.12Opencv4.xCmake4.x_测试Qt编译的opencv4.x的库编译Qt-Opencv库测试流程-①创建一个简单的qt-ui工程配置 & 测试配置库编译环境测试代码百度云-工程(opencv4.xqt5.12的工程)参考文档编译Qt-Opencv库 [嵌入式embed][Qt]Qt5.12Opencv4.xCmake4.x_用Qt…