Springboot集成RabbitMQ
应用场景
一个技术的产生必然有其原因。
消息队列是一个容器,可以对程序产生的消息进行存储。消息队列的主要用途是削峰、异步、解耦,我们用一个实际场景来解释下。
有一家果汁生产企业,张三是采购员,负责采购水果;李四、赵五是配送员,分别负责将苹果、香蕉配送到生产车间。
削峰
传统模式下,张三采购完成,回到公司后,联系李四、赵五配送采购的水果。但是随着公司业务量大增,张三一次性采购的水果,李四、赵五得需要几天才能配送完。所以需要一个仓库,张三采购完成直接放到仓库里,李四、赵五慢慢从仓库取出配送。
此处的仓库就是消息队列,张三是采购消息的生产者,李四、赵五是消费者。当生产的消息太多时,可以使用队列削峰,这样消费者可以慢慢处理消息。
异步
传统模式下,张三采购完成后,需要等待李四、赵五来取,实际上极大浪费了张三的时间。如果直接放入仓库,可以不必等待,直接进行下面的工作。也就是说,张三与李四、赵五的工作是异步的,减少了等待时间。
解耦
之前张三采购完成后,有责任通知李四、赵五来取。万一李四、赵五忘带手机,张三还得联系领导协调处理,说实话张三就是个大老粗,整天为这些破事烦得不行。如果直接放入仓库,张三根本不用管李四、赵五的事情,感觉愉快极了。张三与李四、赵五的工作不再互相依赖,都变得更加简单了,这就是解耦。
RabbitMQ 简介
RabbitMQ 是非常出名的消息中间件,遵循 AMQP 协议,可以跨平台、跨语言使用。 RabbitMQ 具备低时延、高可用的特点,还有简洁易用的可视化管理界面。
安装
本文主要介绍在 Windows 系统下的使用。
最新版的 RabbitMQ 需要 64位的 Erlang 依赖,在 Installing on Windows — RabbitMQ 中找到对应的依赖安装包和软件包安装即可。

在写本文的时候,最新的版本如上图所示。
安装完 RabbitMQ 以后,服务会自动运行,这时环境变量里的 ERLANG_HOME 会自动生成,在”环境变量”中检查是否存在,如果不存在,请在”环境变量”中手动添加,配置 Erlang 环境变量 ERLANG_HOME 。
如果需要手动启动服务的话:

打开命令行命令行,进入 RabbitMQ 的安装目录下的 sbin 目录
输入 rabbitmqctl status
如果出现下图,则说明安装成功了,并且 RabbitMQ 已经启动

乱码是因为 RabbitMQ 需要终端字符集是 UTF-8 但是 Windows 默认不是,可以不用管。
开启 RabbitMQ 可视化管理界面
同样在 sbin 目录下运行 cmd 终端
输入命令 rabbitmq-plugins enable rabbitmq_management
在web浏览器中输入地址:http://localhost:15672/ 输入默认账号 guest 和默认密码 guest 即可登录查看 。
和 Springboot 集成
在 iDEA 下新建项目,并选择以下依赖:

项目创建后,通过 applicaiton.properties 配置 RabbitMQ 的链接信息
spring.rabbitmq.host=localhost # 默认地址
spring.rabbitmq.port=5672 # 默认端口
spring.rabbitmq.username=guest # 默认账号
spring.rabbitmq.password=guest # 默认密码
spring.rabbitmq.virtual-host=/ # 默认虚拟主机 可以理解为 MySQL 中的数据库,可以为每个项目建立一个虚拟主机互不影响
建立 RabbitConfig (RabbitMQ的配置类)
这里我们以入门为主,先以最小化的配置来定义,完成一个基本的生产和消费过程。
package com.syuez.springrabbitmq.config;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
@Configurable
public class RabbitConfig {
/**
* 建立一个叫 hello 的队列配置
* @return 队列
*/
@Bean
public Queue helloQueue() {
return new Queue("hello");
}
}
建立 Sender (消息生产者)
通过注入 RabbitTemplate 接口的实例来实现消息的发送。该生产者会将接收到的字符串转发到名叫 hello 的队列中。
package com.syuez.springrabbitmq.rabbit;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class Sender {
@Resource
private RabbitTemplate rabbitTemplate;
/**
* 发送消息
* @param msg 要发送的消息
*/
public void send(String msg) {
System.out.println("Sender : " + msg);
this.rabbitTemplate.convertAndSend("hello", msg);
}
}
建立 Receiver (消息消费者)
通过 @RabbitListener 注解定义该类对 hello 队列的监听,并用 @RabbitHandler 注解来指定对消息的处理方法。所以,该消费者实现了对 hello 队列的消费,消费操作为输出消息的字符串内容。
package com.syuez.springrabbitmq.rabbit;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@RabbitListener(queuesToDeclare = @Queue("hello"))
public class Receiver {
/**
* 接收到消息的處理方法
* @param message 接收到的消息
*/
@RabbitHandler
public void process(String message) {
System.out.println("Receiver : " + message);
}
}
其中 queuesToDeclare = @Queue("hello") 是自动创建一个叫 hello 的队列。
建立 DemoController
package com.syuez.springrabbitmq.controller;
import com.syuez.springrabbitmq.rabbit.Sender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@Autowired
private Sender sender;
@RequestMapping(value = "/send",method = RequestMethod.GET)
public String send(String msg) {
sender.send(msg);
return "消息: " + msg + ",已发送!";
}
}
启动 Springboot 项目。
打开 http://localhost:15672 查看 RabbitMQ 控制台,点击 Connections 栏,可以看到连接对象,说明已经正常启动了。

点击 Queues 栏可以查看 hello 队列

点击 hello 后可查看详情。
测试
在浏览器打开 localhost:8080/send?msg=测试

完成!
本文参考资料:
SpringBoot - 第二十六章 | RabbitMQ的集成和使用 | J.J.'s Blogs (morosedog.gitlab.io)
Rabbitmq自动创建队列_Matea1024的博客-CSDN博客_rabbitmq自动创建队列
如何删除队列和清空队列数据?_分布式消息服务RabbitMQ版_常见问题_实例问题_华为云 (huaweicloud.com)