SpringBoot 與 RabbitMQ 整合實踐
RabbitMQ服務搭建
這裏介紹三種平臺的搭建方式,分別是docker平臺、centos平臺以及ubuntu平臺。其中docker部署最爲方便,只需搭建好docker平臺,下載鏡像,然後啓動即可。其他兩種平臺分別用兩種方式實現,一是使用各自的軟件管理工具在線安裝,二是下載軟件包離線安裝。
Docker平臺
Docker環境搭建
參考:https://www.runoob.com/docker/ubuntu-docker-install.html
這裏介紹的是ubuntu 16.04系統上搭建docker環境的步驟。
1、如果安裝過docker舊版本,使用以下命令卸載舊版本docker。
apt-get remove docker docker-engine docker.io containerd runc
2、更新倉庫。
apt-get update
3、安裝依賴包。
apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
4、添加docker GPG key,我們使用阿里雲的版本。
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add -
5、添加repository,我們使用阿里雲的版本。
add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
6、再次更新倉庫
apt-get update
7、安裝最新版本的docker ce和containerd.io。
apt-get install docker-ce docker-ce-cli containerd.io
8、檢查安裝是否成功。
docker --version
9、設置開機自動啓動並啓動docker-ce。
systemctl enable docker
systemctl start docker
10、設置docker設置國內鏡像源,創建或修改 /etc/docker/daemon.json 文件,修改爲如下形式。
vim /etc/docker/daemon.json
# vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
11、重啓docker服務。
systemctl stop docker
systemctl start docker
12、查看docke配置信息。
docker info
從圖中可以看到鏡像源已經修改爲國內源了。
安裝RabbitMQ鏡像
1、使用docker run命令拉取並運行RabbitMQ鏡像。
docker run -d --name my-rabbitmq --hostname my-rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management
docker run 命令簡介
-d 後臺運行容器,並返回容器ID
–name 容器別名
–hostname 機器實例的名稱
-p 端口映射
rabbitmq:3-management 表示包含管理工具
2、RabbitMQ鏡像及容器操作
docker images 查看本地鏡像列表
docker ps -a 查看容器列表,運行的或未運行的
docker start xxx 啓動指定容器id或名稱的容器
docker stop xxx 停止指定容器id或名稱的容器
3、登錄RabbitMQ管理頁面
在瀏覽器輸入 http://ip:15672 打開RabbitMQ管理頁面,默認登錄用戶名 guest,密碼也是 guest。
Ubuntu 平臺
使用apt-get從安裝源在線安裝
首先配置國內軟件源,這樣可以大幅提高軟件下載速度。
1、更新倉庫
apt-get update
2、由於rabbitMq需要erlang語言的支持,在安裝rabbitMq之前需要安裝erlang,執行命令:
apt-get install erlang-nox
3、驗證erlang安裝結果,執行命令:
erl
順利進入erlang命令行,表示安裝成功。
4、安裝RabbitMQ Server,執行命令:
apt-get install rabbitmq-server
5、驗證安裝結果,執行命令:
systemctl status rabbitmq-server
6、設置開機自動啓動rabbitmq-server。
systemctl enable rabbitmq-server
服務控制命令介紹:
systemctl start rabbitmq-server 啓動rabbitmq-server
systemctl stop rabbitmq-server 停止rabbitmq-server
systemctl restart rabbitmq-server 重啓rabbitmq-server
7、啓用rabbitmq的管理工具插件。
查看插件列表
rabbitmq-plugins list
啓用 rabbitmq_management 插件
rabbitmq-plugins enable rabbitmq_management
重啓rabbitmq-server服務
systemctl restart rabbitmq-server
在瀏覽器輸入地址http://ip:15672可以打開管理頁面。
8、創建web登錄賬戶,並賦予管理員角色。
rabbitmq-server默認的guest用戶只能本地登錄,可以創建一個新用戶實現遠程登錄web頁面。
rabbitmqctl add_user admin netinfo,123
給admin用戶賦予管理員權限。
rabbitmqctl set_user_tags admin administrator
這樣就可以使用admin用戶登錄web管理頁面了。
下載deb軟件包離線安裝
1、下載所需的deb軟件包
RabbitMQ主要依賴兩個組件,erlang和socat,需要下載以下三個軟件包:
esl-erlang_22.3-1ubuntuxenial_amd64.deb
rabbitmq-server_3.8.3-1_all.deb
socat_1.7.2.4-2_amd64.deb
erlang下載地址:
https://www.erlang-solutions.com/resources/download.html
選擇 Ubuntu Xenial (64-bit) 版本。
socat下載地址:
https://packages.debian.org/stretch/amd64/socat/download
選擇亞洲區中國的站點下載,Asia/ftp.cn.debian.org/debian
http://ftp.cn.debian.org/debian/pool/main/s/socat/socat_1.7.3.1-2+deb9u1_amd64.deb
rabbitmq-server下載地址:
https://packagecloud.io/rabbitmq/rabbitmq-server
選擇 ubuntu/xenial 版本。
2、將軟件包複製到Ubuntu服務器上,這裏放在了/opt目錄下。
3、安裝軟件包。
安裝erlang:
dpkg -i esl-erlang_22.3-1~ubuntu~xenial_amd64.deb
這一步有可能報缺少libwxbase依賴的錯誤,按照提示安裝好依賴,輸入命令:
apt-get update
apt-get install libwxbase3.0-0v5
又會報一個錯誤,提示使用 apt-get -f install 命令,根據提示輸入命令:
apt-get -f install
等待一會,正在安裝依賴包。
驗證erlang安裝結果,執行命令:
erl
安裝socat:
dpkg -i socat_1.7.2.4-2_amd64.deb
安裝rabbitmq-server:
dpkg -i rabbitmq-server_3.8.3-1_all.deb
安裝完成。
接下來服務啓動、開機啓動、啓用管理插件、創建web登錄賬戶等操作與前文相同,此處不再重複。
CentOS平臺
這裏CentOS系統的版本是CentOS7。
使用yum包管理工具在線安裝
首先配置國內軟件源,這樣可以大幅提高軟件下載速度。
1、安裝依賴:
yum -y install gcc glibc-devel make ncurses-devel openssl-devel xmlto perl wget gtk2-devel binutils-devel
2、安裝erlang:
curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
yum install erlang
3、安裝rabbitmq-server:
curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
yum install rabbitmq-server
安裝完成。
接下來服務啓動、開機啓動、啓用管理插件、創建web登錄賬戶等操作與前文相同,此處不再重複。
使用rpm軟件包離線安裝
安裝RabbitMQ需要以下三個軟件包:
erlang-22.3-1.el7.x86_64.rpm
rabbitmq-server-3.8.3-1.el7.noarch.rpm
socat-1.7.3.2-2.el7.x86_64.rpm
1、下載rpm軟件包。
下載 erlang:
https://packagecloud.io/rabbitmq/erlang
選擇 el/7 版本。
下載socat:
http://www.rpmfind.net/linux/rpm2html/search.php?query=socat(x86-64)
選擇 el/7 x86_64 版本,即:socat-1.7.3.2-2.el7.x86_64.rpm。
下載rabbitmq-server:
https://packagecloud.io/rabbitmq/rabbitmq-server
選擇 el/7 版本。
2、將rmp軟件包複製到服務器上,本例放在了/opt 目錄下。
3、安裝rpm軟件包。
安裝erlang:
rpm -ivh erlang-22.3-1.el7.x86_64.rpm
安裝socat:
rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm
安裝rabbitmq-server:
rpm -ivh rabbitmq-server-3.8.3-1.el7.noarch.rpm
安裝完成。
接下來服務啓動、開機啓動、啓用管理插件、創建web登錄賬戶等操作與前文相同,此處不再重複。
SpringBoot 集成RabbitMQ
這裏通過一個簡單的實例介紹SpringBoot集成RabbitMQ的一般步驟。實例包括兩個項目,分別作爲消息生產者(RabbitMQ Producer)和消費者(RabbitMQ Consumer),項目結構如下圖所示:
項目配置
1、添加依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、配置RabbitMQ服務連接信息。
在application.properties配置文件中添加以下配置:
spring.rabbitmq.host=192.168.1.20
spring.rabbitmq.port=5672
spring.rabbitmq.username=rabbit
spring.rabbitmq.password=rabbit
簡單隊列
P:消息的生產者
C:消息的消費者
紅色:隊列
生產者將消息發送到隊列,消費者從隊列中獲取消息。
消息生產者
1、添加DirectRabbitConfig
@Configuration
public class DirectRabbitConfig {
@Bean
public Queue TestDirectQueue() {
return new Queue("TestDirectQueue", true);
}
@Bean
public DirectExchange TestDirectExchange() {
return new DirectExchange("TestDirectExchange");
}
@Bean
public Binding bindingDirect() {
return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting");
}
}
2、添加測試Controller
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping(value = "/send_direct_msg", method = RequestMethod.POST)
public String sendDirectMessage(@RequestParam("msg") String msg) {
String msgId = String.valueOf(UUID.randomUUID());
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String msgData = "Direct message.\t" + msg;
Map<String, Object> map = new HashMap<>();
map.put("msg_id", msgId);
map.put("msg_data", msgData);
map.put("create_time", createTime);
rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);
return "ok";
}
}
3、啓動項目,啓動Rest Client測試消息發送
消息消費者
1、添加DirectRabbitConfig
內容與消息生產者一樣,也可以不添加這個配置。
2、添加DirectReceiver
@Component
@RabbitListener(queues = "TestDirectQueue")
public class DirectReceiver {
@RabbitHandler
public void process(Map msgMap) {
System.out.println("DirectReceiver消費者收到消息 : " + msgMap.toString());
}
}
3、啓動項目,查看日誌
可見,消息已經接收到。
訂閱模式
解讀:
1、1個生產者,多個消費者
2、每一個消費者都有自己的一個隊列
3、生產者沒有將消息直接發送到隊列,而是發送到了交換機
4、每個隊列都要綁定到交換機
5、生產者發送的消息,經過交換機,到達隊列,實現,一個消息被多個消費者獲取的目的
注意:一個消費者隊列可以有多個消費者實例,只有其中一個消費者實例會消費
消息生產者
1、添加TopicRabbitConfig
@Configuration
public class TopicRabbitConfig {
public static final String MAN = "topic.man";
public static final String WOMAN = "topic.woman";
@Bean
public Queue firstQueue() {
return new Queue(MAN);
}
@Bean
public Queue secondQueue() {
return new Queue(WOMAN);
}
@Bean
public TopicExchange exchange() {
return new TopicExchange("topicExchange");
}
@Bean
public Binding bindingExchangeMessage() {
return BindingBuilder.bind(firstQueue()).to(exchange()).with(MAN);
}
@Bean
public Binding bindingExchangeMessage2() {
return BindingBuilder.bind(secondQueue()).to(exchange()).with("topic.#");
}
}
2、添加測試Controller
@RequestMapping(value = "/send_topic_msg_1", method = RequestMethod.POST)
public String sendTopicMessage1(@RequestParam("msg") String msg) {
String msgId = String.valueOf(UUID.randomUUID());
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String msgData = "Topic message 1.\t" + msg;
Map<String, Object> map = new HashMap<>();
map.put("msg_id", msgId);
map.put("msg_data", msgData);
map.put("create_time", createTime);
rabbitTemplate.convertAndSend("topicExchange", "topic.man", map);
return "ok";
}
@RequestMapping(value = "/send_topic_msg_2", method = RequestMethod.POST)
public String sendTopicMessage2(@RequestParam("msg") String msg) {
String msgId = String.valueOf(UUID.randomUUID());
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String msgData = "Topic message 2.\t" + msg;
Map<String, Object> map = new HashMap<>();
map.put("msg_id", msgId);
map.put("msg_data", msgData);
map.put("create_time", createTime);
rabbitTemplate.convertAndSend("topicExchange", "topic.woman", map);
return "ok";
}
3、啓動項目,啓動Rest Client測試消息發送
消息消費者
1、添加TopicRabbitConfig
內容與消息生產者一樣。
2、添加TopicReceiver
@Component
@RabbitListener(queues = "topic.man")
public class TopicManReceiver {
@RabbitHandler
public void process(Map msgMap) {
System.out.println("TopicManReceiver消費者收到消息 : " + msgMap.toString());
}
}
@Component
@RabbitListener(queues = "topic.woman")
public class TopicTotalReceiver {
@RabbitHandler
public void process(Map msgMap) {
System.out.println("TopicTotalReceiver消費者收到消息 : " + msgMap.toString());
}
}
3、啓動項目,查看日誌
扇形模式
消息生產者
1、添加FanoutRabbitConfig
@Configuration
public class FanoutRabbitConfig {
@Bean
public Queue queueA() {
return new Queue("fanout.A");
}
@Bean
public Queue queueB() {
return new Queue("fanout.B");
}
@Bean
public Queue queueC() {
return new Queue("fanout.C");
}
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange("fanoutExchange");
}
@Bean
public Binding bindingExchangeA() {
return BindingBuilder.bind(queueA()).to(fanoutExchange());
}
@Bean
public Binding bindingExchangeB() {
return BindingBuilder.bind(queueB()).to(fanoutExchange());
}
@Bean
public Binding bindingExchangeC() {
return BindingBuilder.bind(queueC()).to(fanoutExchange());
}
}
2、添加測試Controller
@RequestMapping(value = "/send_fanout_msg", method = RequestMethod.POST)
public String sendFanoutMessage(@RequestParam("msg") String msg) {
String msgId = String.valueOf(UUID.randomUUID());
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String msgData = "Fanout message.\t" + msg;
Map<String, Object> map = new HashMap<>();
map.put("msg_id", msgId);
map.put("msg_data", msgData);
map.put("create_time", createTime);
rabbitTemplate.convertAndSend("fanoutExchange", null, map);
return "ok";
}
3、啓動項目,啓動Rest Client測試消息發送
消息消費者
1、添加FanoutRabbitConfig
內容與消息生產者一樣。
2、添加FanoutReceiver
@Component
@RabbitListener(queues = "fanout.A")
public class FanoutReceiverA {
@RabbitHandler
public void process(Map msgMap) {
System.out.println("FanoutReceiverA消費者收到消息 : " + msgMap.toString());
}
}
@Component
@RabbitListener(queues = "fanout.B")
public class FanoutReceiverB {
@RabbitHandler
public void process(Map msgMap) {
System.out.println("FanoutReceiverB消費者收到消息 : " + msgMap.toString());
}
}
@Component
@RabbitListener(queues = "fanout.C")
public class FanoutReceiverC {
@RabbitHandler
public void process(Map msgMap) {
System.out.println("FanoutReceiverC消費者收到消息 : " + msgMap.toString());
}
}
3、啓動項目,查看日誌