Springboot集成RabbitMQ

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)

Spring Boot RabbitMQ 应用场景丨慕课网教程 (imooc.com)

RabbitMQ的安装和配置化可视界面 - wade&luffy - 博客园 (cnblogs.com)