欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot中RabbitMQ集群的搭建詳解

 更新時間:2021年12月13日 15:21:29   作者:_江南一點雨  
單個的?RabbitMQ?肯定無法實現(xiàn)高可用,要想高可用,還得上集群。這篇文章主要介紹了SpringBoot中RabbitMQ集群的兩種模式的搭建:普通集群搭建和鏡像集群搭建,需要的朋友可以參考一下

單個的 RabbitMQ 肯定無法實現(xiàn)高可用,要想高可用,還得上集群。

今天松哥就來和大家聊一聊 RabbitMQ 集群的搭建。

1. 兩種模式

說到集群,小伙伴們可能第一個問題是,如果我有一個 RabbitMQ 集群,那么是不是我的消息集群中的每一個實例都保存一份呢?

這其實就涉及到 RabbitMQ 集群的兩種模式:

  • 普通集群
  • 鏡像集群

1.1 普通集群

普通集群模式,就是將 RabbitMQ 部署到多臺服務(wù)器上,每個服務(wù)器啟動一個 RabbitMQ 實例,多個實例之間進行消息通信。

此時我們創(chuàng)建的隊列 Queue,它的元數(shù)據(jù)(主要就是 Queue 的一些配置信息)會在所有的 RabbitMQ 實例中進行同步,但是隊列中的消息只會存在于一個 RabbitMQ 實例上,而不會同步到其他隊列。

當我們消費消息的時候,如果連接到了另外一個實例,那么那個實例會通過元數(shù)據(jù)定位到 Queue 所在的位置,然后訪問 Queue 所在的實例,拉取數(shù)據(jù)過來發(fā)送給消費者。

這種集群可以提高 RabbitMQ 的消息吞吐能力,但是無法保證高可用,因為一旦一個 RabbitMQ 實例掛了,消息就沒法訪問了,如果消息隊列做了持久化,那么等 RabbitMQ 實例恢復后,就可以繼續(xù)訪問了;如果消息隊列沒做持久化,那么消息就丟了。

大致的流程圖如下圖:

1.2 鏡像集群

它和普通集群最大的區(qū)別在于 Queue 數(shù)據(jù)和原數(shù)據(jù)不再是單獨存儲在一臺機器上,而是同時存儲在多臺機器上。也就是說每個 RabbitMQ 實例都有一份鏡像數(shù)據(jù)(副本數(shù)據(jù))。每次寫入消息的時候都會自動把數(shù)據(jù)同步到多臺實例上去,這樣一旦其中一臺機器發(fā)生故障,其他機器還有一份副本數(shù)據(jù)可以繼續(xù)提供服務(wù),也就實現(xiàn)了高可用。

大致流程圖如下圖:

1.3 節(jié)點類型

RabbitMQ 中的節(jié)點類型有兩種:

  • RAM node:內(nèi)存節(jié)點將所有的隊列、交換機、綁定、用戶、權(quán)限和 vhost 的元數(shù)據(jù)定義存儲在內(nèi)存中,好處是可以使得交換機和隊列聲明等操作速度更快。
  • Disk node:將元數(shù)據(jù)存儲在磁盤中,單節(jié)點系統(tǒng)只允許磁盤類型的節(jié)點,防止重啟 RabbitMQ 的時候,丟失系統(tǒng)的配置信息

RabbitMQ 要求在集群中至少有一個磁盤節(jié)點,所有其他節(jié)點可以是內(nèi)存節(jié)點,當節(jié)點加入或者離開集群時,必須要將該變更通知到至少一個磁盤節(jié)點。如果集群中唯一的一個磁盤節(jié)點崩潰的話,集群仍然可以保持運行,但是無法進行其他操作(增刪改查),直到節(jié)點恢復。為了確保集群信息的可靠性,或者在不確定使用磁盤節(jié)點還是內(nèi)存節(jié)點的時候,建議直接用磁盤節(jié)點。

2. 搭建普通集群

2.1 預備知識

大致的結(jié)構(gòu)了解了,接下來我們就把集群給搭建起來。先從普通集群開始,我們就使用 docker 來搭建。

搭建之前,有兩個預備知識需要大家了解:

  1. 搭建集群時,節(jié)點中的 Erlang Cookie 值要一致,默認情況下,文件在 /var/lib/rabbitmq/.erlang.cookie,我們在用 docker 創(chuàng)建 RabbitMQ 容器時,可以為之設(shè)置相應(yīng)的 Cookie 值。
  2. RabbitMQ 是通過主機名來連接服務(wù),必須保證各個主機名之間可以 ping 通??梢酝ㄟ^編輯 /etc/hosts 來手工添加主機名和 IP 對應(yīng)關(guān)系。如果主機名 ping 不通,RabbitMQ 服務(wù)啟動會失?。ㄈ绻覀兪窃诓煌姆?wù)器上搭建 RabbitMQ 集群,大家需要注意這一點,接下來的 2.2 小結(jié),我們將通過 Docker 的容器連接 link 來實現(xiàn)容器之間的訪問,略有不同)。

2.2 開始搭建

執(zhí)行如下命令創(chuàng)建三個 RabbitMQ 容器:

docker run -d --hostname rabbit01 --name mq01 -p 5671:5672 -p 15671:15672 -e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" rabbitmq:3-management
docker run -d --hostname rabbit02 --name mq02 --link mq01:mylink01 -p 5672:5672 -p 15672:15672 -e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" rabbitmq:3-management
docker run -d --hostname rabbit03 --name mq03 --link mq01:mylink02 --link mq02:mylink03 -p 5673:5672 -p 15673:15672 -e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" rabbitmq:3-management

運行結(jié)果如下:

三個節(jié)點現(xiàn)在就啟動好了,注意在 mq02 和 mq03 中,分別使用了 --link 參數(shù)來實現(xiàn)容器連接,關(guān)于這個參數(shù),如果大家不懂,可以在公眾號江南一點雨后臺回復 docker,由松哥寫的 docker 入門教程,里邊有講這個。這里我就不啰嗦了。另外還需要注意,mq03 容器中要既能夠連接 mq01 也能夠連接 mq02。

接下來進入到 mq02 容器中,首先查看一下 hosts 文件,可以看到我們配置的容器連接已經(jīng)生效了:

將來在 mq02 容器中,就可以通過 mylink01 或者 rabbit01 訪問到 mq01 容器了。

接下來我們開始集群的配置。

分別執(zhí)行如下命令將 mq02 容器加入集群中:

rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit01
rabbitmqctl start_app

接下來輸入如下命令我們可以查看集群的狀態(tài):

rabbitmqctl cluster_status

可以看到,集群中已經(jīng)有兩個節(jié)點了。

接下來通過相同的方式將 mq03 也加入到集群中:

rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit01
rabbitmqctl start_app

接下來,我們可以查看集群信息:

可以看到,此時集群中已經(jīng)有三個節(jié)點了。

其實,這個時候,我們也可以通過網(wǎng)頁來查看集群信息,在三個 RabbitMQ 實例的 Web 端首頁,都可以看到如下內(nèi)容:

2.3 代碼測試

接下來我們來簡單測試一下這個集群。

我們創(chuàng)建一個名為 mq_cluster_demo 的父工程,然后在其中創(chuàng)建兩個子工程。

第一個子工程名為 provider,是一個消息生產(chǎn)者,創(chuàng)建時引入 Web 和 RabbitMQ 依賴,如下:

然后配置 applicaiton.properties,內(nèi)容如下(注意集群配置):

spring.rabbitmq.addresses=localhost:5671,localhost:5672,localhost:5673
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

接下來提供一個簡單的隊列,如下:

@Configuration
public class RabbitConfig {
    public static final String MY_QUEUE_NAME = "my_queue_name";
    public static final String MY_EXCHANGE_NAME = "my_exchange_name";
    public static final String MY_ROUTING_KEY = "my_queue_name";

    @Bean
    Queue queue() {
        return new Queue(MY_QUEUE_NAME, true, false, false);
    }

    @Bean
    DirectExchange directExchange() {
        return new DirectExchange(MY_EXCHANGE_NAME, true, false);
    }

    @Bean
    Binding binding() {
        return BindingBuilder.bind(queue())
                .to(directExchange())
                .with(MY_ROUTING_KEY);
    }
}

這個沒啥好說的,都是基本內(nèi)容,接下來我們在單元測試中進行消息發(fā)送測試:

@SpringBootTest
class ProviderApplicationTests {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Test
    void contextLoads() {
        rabbitTemplate.convertAndSend(null, RabbitConfig.MY_QUEUE_NAME, "hello 江南一點雨");
    }

}

這條消息發(fā)送成功之后,在 RabbitMQ 的 Web 管理端,我們會看到三個 RabbitMQ 實例上都會顯示有一條消息,但是實際上消息本身只存在于一個 RabbitMQ 實例。

接下來我們再創(chuàng)建一個消息消費者,消息消費者的依賴以及配置和消息生產(chǎn)者都是一模一樣,我就不重復了,消息消費者中增加一個消息接收器:

@Component
public class MsgReceiver {

    @RabbitListener(queues = RabbitConfig.MY_QUEUE_NAME)
    public void handleMsg(String msg) {
        System.out.println("msg = " + msg);
    }
}

當消息消費者啟動成功后,這個方法中只收到一條消息,進一步驗證了我們搭建的 RabbitMQ 集群是沒問題的。

2.4 反向測試

接下來松哥再舉兩個反例,以證明消息并沒有同步到其他 RabbitMQ 實例。

確保三個 RabbitMQ 實例都是啟動狀態(tài),關(guān)閉掉 Consumer,然后通過 provider 發(fā)送一條消息,發(fā)送成功之后,關(guān)閉 mq01 實例,然后啟動 Consumer 實例,此時 Consumer 實例并不會消費消息,反而會報錯說 mq01 實例連接不上,這個例子就可以說明消息在 mq01 上,并沒有同步到另外兩個 MQ 上。相反,如果 provider 發(fā)送消息成功之后,我們沒有關(guān)閉 mq01 實例而是關(guān)閉了 mq02 實例,那么你就會發(fā)現(xiàn)消息的消費不受影響。

3. 搭建鏡像集群

所謂的鏡像集群模式并不需要額外搭建,只需要我們將隊列配置為鏡像隊列即可。

這個配置可以通過網(wǎng)頁配置,也可以通過命令行配置,我們分別來看。

3.1 網(wǎng)頁配置鏡像隊列

先來看看網(wǎng)頁上如何配置鏡像隊列。

點擊 Admin 選項卡,然后點擊右邊的 Policies,再點擊 Add/update a policy,如下圖:

接下來添加一個策略,如下圖:

各參數(shù)含義如下:

Name: policy 的名稱。

Pattern: queue 的匹配模式(正則表達式)。

Definition:鏡像定義,主要有三個參數(shù):ha-mode, ha-params, ha-sync-mode。

  • ha-mode:指明鏡像隊列的模式,有效值為 all、exactly、nodes。其中 all 表示在集群中所有的節(jié)點上進行鏡像(默認即此);exactly 表示在指定個數(shù)的節(jié)點上進行鏡像,節(jié)點的個數(shù)由 ha-params 指定;nodes 表示在指定的節(jié)點上進行鏡像,節(jié)點名稱通過 ha-params 指定。
  • ha-params:ha-mode 模式需要用到的參數(shù)。
  • ha-sync-mode:進行隊列中消息的同步方式,有效值為 automatic 和 manual。

priority 為可選參數(shù),表示 policy 的優(yōu)先級。

配置完成后,點擊下面的 add/update policy 按鈕,完成策略的添加,如下:

添加完成后,我們可以進行一個簡單的測試。

首先確認三個 RabbitMQ 都啟動了,然后用上面的 provider 向消息隊列發(fā)送一條消息。

發(fā)完之后關(guān)閉 mq01 實例。

接下來啟動 consumer,此時發(fā)現(xiàn) consumer 可以完成消息的消費(注意和前面的反向測試區(qū)分),這就說明鏡像隊列已經(jīng)搭建成功了。

3.2 命令行配置鏡像隊列

命令行的配置格式如下:

rabbitmqctl set_policy [-p vhost] [--priority priority] [--apply-to apply-to] {name} {pattern} {definition}

舉一個簡單的配置案例:

rabbitmqctl set_policy -p / --apply-to queues my_queue_mirror "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

4. 小結(jié)

好啦,這就是松哥和大家分享的 RabbitMQ 中的集群搭建,感興趣的小伙伴趕緊去試試吧~

以上就是SpringBoot中RabbitMQ集群的搭建詳解的詳細內(nèi)容,更多關(guān)于SpringBoot RabbitMQ集群搭建的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 利用java實現(xiàn)郵箱群發(fā)功能

    利用java實現(xiàn)郵箱群發(fā)功能

    這篇文章主要為大家詳細介紹了利用java實現(xiàn)郵箱群發(fā)功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 深入了解MyBatis分頁機制

    深入了解MyBatis分頁機制

    在企業(yè)項目的數(shù)據(jù)庫操作中,分頁查詢是一個常見需求,尤其當數(shù)據(jù)量龐大時,MyBatis作為我們Java開發(fā)者的持久層框架,為分頁提供了靈活的支持,本篇文章我們將深入探討MyBatis的分頁機制,使我們在實際開發(fā)項目中運用自如,需要的朋友可以參考下
    2023-12-12
  • java實現(xiàn)訂餐系統(tǒng)

    java實現(xiàn)訂餐系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)訂餐系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Java concurrency線程池之Callable和Future_動力節(jié)點Java學院整理

    Java concurrency線程池之Callable和Future_動力節(jié)點Java學院整理

    這篇文章主要為大家詳細介紹了Java concurrency線程池之Callable和Future,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Java中的同步與異步詳細介紹

    Java中的同步與異步詳細介紹

    這篇文章主要介紹了Java中的同步與異步詳細介紹,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • java實用小技巧之判斷l(xiāng)ist是否有重復項簡單例子

    java實用小技巧之判斷l(xiāng)ist是否有重復項簡單例子

    這篇文章主要給大家介紹了關(guān)于java實用小技巧之判斷l(xiāng)ist是否有重復項的相關(guān)資料,在開發(fā)工作中我們有時需要去判斷List集合中是否含有重復的元素,需要的朋友可以參考下
    2023-10-10
  • 淺談對java中鎖的理解

    淺談對java中鎖的理解

    本文主要講述java中鎖的相關(guān)知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-03-03
  • 基于SpringBoot實現(xiàn)輕量級的動態(tài)定時任務(wù)調(diào)度的方法

    基于SpringBoot實現(xiàn)輕量級的動態(tài)定時任務(wù)調(diào)度的方法

    本文介紹了如何在SpringBoot框架中實現(xiàn)輕量級的動態(tài)定時任務(wù)調(diào)度,通過將任務(wù)以類為基礎(chǔ)單位,并通過配置數(shù)據(jù)進行任務(wù)讀取和反射生成任務(wù)對象,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Java 創(chuàng)建PDF打印小冊子案例

    Java 創(chuàng)建PDF打印小冊子案例

    這篇文章主要給大家分享Java 創(chuàng)建PDF打印小冊子案例,PDF打印小冊子是指將PDF格式文檔在打印成刊物前需要提前進行的頁面排版,以便在打印后裝訂成冊,下面文章內(nèi)容我們將下面以Java代碼展示如何來實現(xiàn),需要的朋友可以參考一下
    2021-10-10
  • Java中HTTP接口請求重試的實現(xiàn)方式

    Java中HTTP接口請求重試的實現(xiàn)方式

    HTTP接口請求重試是指在請求失敗時,再次發(fā)起請求的機制,在實際應(yīng)用中,由于網(wǎng)絡(luò)波動、服務(wù)器故障等原因,HTTP接口請求可能會失敗,為了保證系統(tǒng)的可用性和穩(wěn)定性,需要對HTTP接口請求進行重試,所以本文給大家介紹了HTTP接口請求重試的實現(xiàn)方式,需要的朋友可以參考下
    2024-01-01

最新評論