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

查看docker配置信息
從圖中可以看到鏡像源已經修改爲國內源了。

安裝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。
RabbitMQ管理頁面

Ubuntu 平臺

使用apt-get從安裝源在線安裝

首先配置國內軟件源,這樣可以大幅提高軟件下載速度。

1、更新倉庫

apt-get update

2、由於rabbitMq需要erlang語言的支持,在安裝rabbitMq之前需要安裝erlang,執行命令:

apt-get install erlang-nox

3、驗證erlang安裝結果,執行命令:

erl

驗證安裝erlang
順利進入erlang命令行,表示安裝成功。

4、安裝RabbitMQ Server,執行命令:

apt-get install rabbitmq-server

5、驗證安裝結果,執行命令:

systemctl status rabbitmq-server

驗證RabbitMQ安裝
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管理頁面了。
登錄RabbitMQ管理頁面

下載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、啓動項目,查看日誌

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章