亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot中RabbitMQ集群的搭建詳解

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

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

今天松哥就來(lái)和大家聊一聊 RabbitMQ 集群的搭建。

1. 兩種模式

說(shuō)到集群,小伙伴們可能第一個(gè)問(wèn)題是,如果我有一個(gè) RabbitMQ 集群,那么是不是我的消息集群中的每一個(gè)實(shí)例都保存一份呢?

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

  • 普通集群
  • 鏡像集群

1.1 普通集群

普通集群模式,就是將 RabbitMQ 部署到多臺(tái)服務(wù)器上,每個(gè)服務(wù)器啟動(dòng)一個(gè) RabbitMQ 實(shí)例,多個(gè)實(shí)例之間進(jìn)行消息通信。

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

當(dāng)我們消費(fèi)消息的時(shí)候,如果連接到了另外一個(gè)實(shí)例,那么那個(gè)實(shí)例會(huì)通過(guò)元數(shù)據(jù)定位到 Queue 所在的位置,然后訪問(wèn) Queue 所在的實(shí)例,拉取數(shù)據(jù)過(guò)來(lái)發(fā)送給消費(fèi)者。

這種集群可以提高 RabbitMQ 的消息吞吐能力,但是無(wú)法保證高可用,因?yàn)橐坏┮粋€(gè) RabbitMQ 實(shí)例掛了,消息就沒(méi)法訪問(wèn)了,如果消息隊(duì)列做了持久化,那么等 RabbitMQ 實(shí)例恢復(fù)后,就可以繼續(xù)訪問(wèn)了;如果消息隊(duì)列沒(méi)做持久化,那么消息就丟了。

大致的流程圖如下圖:

1.2 鏡像集群

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

大致流程圖如下圖:

1.3 節(jié)點(diǎn)類(lèi)型

RabbitMQ 中的節(jié)點(diǎn)類(lèi)型有兩種:

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

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

2. 搭建普通集群

2.1 預(yù)備知識(shí)

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

搭建之前,有兩個(gè)預(yù)備知識(shí)需要大家了解:

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

2.2 開(kāi)始搭建

執(zhí)行如下命令創(chuàng)建三個(gè) 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

運(yùn)行結(jié)果如下:

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

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

將來(lái)在 mq02 容器中,就可以通過(guò) mylink01 或者 rabbit01 訪問(wèn)到 mq01 容器了。

接下來(lái)我們開(kāi)始集群的配置。

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

rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit01
rabbitmqctl start_app

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

rabbitmqctl cluster_status

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

接下來(lái)通過(guò)相同的方式將 mq03 也加入到集群中:

rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit01
rabbitmqctl start_app

接下來(lái),我們可以查看集群信息:

可以看到,此時(shí)集群中已經(jīng)有三個(gè)節(jié)點(diǎn)了。

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

2.3 代碼測(cè)試

接下來(lái)我們來(lái)簡(jiǎn)單測(cè)試一下這個(gè)集群。

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

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

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

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

接下來(lái)提供一個(gè)簡(jiǎn)單的隊(duì)列,如下:

@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);
    }
}

這個(gè)沒(méi)啥好說(shuō)的,都是基本內(nèi)容,接下來(lái)我們?cè)趩卧獪y(cè)試中進(jìn)行消息發(fā)送測(cè)試:

@SpringBootTest
class ProviderApplicationTests {

    @Autowired
    RabbitTemplate rabbitTemplate;

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

}

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

接下來(lái)我們?cè)賱?chuàng)建一個(gè)消息消費(fèi)者,消息消費(fèi)者的依賴(lài)以及配置和消息生產(chǎn)者都是一模一樣,我就不重復(fù)了,消息消費(fèi)者中增加一個(gè)消息接收器:

@Component
public class MsgReceiver {

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

當(dāng)消息消費(fèi)者啟動(dòng)成功后,這個(gè)方法中只收到一條消息,進(jìn)一步驗(yàn)證了我們搭建的 RabbitMQ 集群是沒(méi)問(wèn)題的。

2.4 反向測(cè)試

接下來(lái)松哥再舉兩個(gè)反例,以證明消息并沒(méi)有同步到其他 RabbitMQ 實(shí)例。

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

3. 搭建鏡像集群

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

這個(gè)配置可以通過(guò)網(wǎng)頁(yè)配置,也可以通過(guò)命令行配置,我們分別來(lái)看。

3.1 網(wǎng)頁(yè)配置鏡像隊(duì)列

先來(lái)看看網(wǎng)頁(yè)上如何配置鏡像隊(duì)列。

點(diǎn)擊 Admin 選項(xiàng)卡,然后點(diǎn)擊右邊的 Policies,再點(diǎn)擊 Add/update a policy,如下圖:

接下來(lái)添加一個(gè)策略,如下圖:

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

Name: policy 的名稱(chēng)。

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

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

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

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

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

添加完成后,我們可以進(jìn)行一個(gè)簡(jiǎn)單的測(cè)試。

首先確認(rèn)三個(gè) RabbitMQ 都啟動(dòng)了,然后用上面的 provider 向消息隊(duì)列發(fā)送一條消息。

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

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

3.2 命令行配置鏡像隊(duì)列

命令行的配置格式如下:

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

舉一個(gè)簡(jiǎn)單的配置案例:

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

4. 小結(jié)

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

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

相關(guān)文章

最新評(píng)論