搭建 RabbitMQ Server 高可用集群

来源:https://www.cnblogs.com/xishuai/archive/2018/04/27/centos-rabbitmq-cluster-and-haproxy.html
-Advertisement-
Play Games

閱讀目錄: 準備工作 搭建 RabbitMQ Server 單機版 RabbitMQ Server 高可用集群相關概念 搭建 RabbitMQ Server 高可用集群 搭建 HAProxy 負載均衡 因為公司測試伺服器暫不能用,只能在自己電腦上重新搭建一下 RabbitMQ Server 高可用集 ...


閱讀目錄:

  • 準備工作
  • 搭建 RabbitMQ Server 單機版
  • RabbitMQ Server 高可用集群相關概念
  • 搭建 RabbitMQ Server 高可用集群
  • 搭建 HAProxy 負載均衡

因為公司測試伺服器暫不能用,只能在自己電腦上重新搭建一下 RabbitMQ Server 高可用集群,正好把這個過程記錄下來,以便日後查看。

公司測試伺服器上的 RabbitMQ 集群,我搭建的是三台伺服器,因為自己電腦空間有限,這邊只能搭建兩台伺服器用作高可用集群,用的是 Vagrant 虛擬機管理工具。

環境介紹:

RabbitMQ 節點 IP 地址 工作模式
node1 192.168.1.50 DISK CentOS 7.0 - 64位
node2 192.168.1.51 DISK CentOS 7.0 - 64位

整體架構:

1. 準備工作

首先,在node1伺服器上,修改vi /etc/hostname

node1

node2伺服器上,修改vi /etc/hostname

node2

然後在node1伺服器上,修改vi /etc/hosts

node1 192.168.1.50
node2 192.168.1.51
127.0.0.1   node1
::1         node1

node2伺服器上,修改vi /etc/hosts

192.168.1.50 node1
192.168.1.51 node2
127.0.0.1   node2
::1         node2

然後查看下hostnamectl status,如果不正確的話,需要再進行設置下:

[root@node1 ~]# hostnamectl status
   Static hostname: node1
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 241163503ce842c489360d0a48a606fc
           Boot ID: cdb59c025cb447e3afed7317af78979e
    Virtualization: oracle
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-229.el7.x86_64
      Architecture: x86_64
[root@node1 ~]# hostnamectl --static set-hostname node1

為了後面我們安裝的順利,我們最好再配置一下代理:

[root@node1 ~]# export http_proxy=http://192.168.1.44:1087;export https_proxy=http://192.168.1.44:1087;
[root@node1 ~]# curl ip.cn
當前 IP:104.245.13.31 來自:美國 Linost

2. 搭建 RabbitMQ Server 單機版

下麵以node1伺服器做演示示例。

首先,更新軟體包和存儲庫:

[root@node1 ~]# yum -y update

然後安裝 Erlang(RabbitMQ 運行需要 Erlang 環境):

[root@node1 ~]# vi /etc/yum.repos.d/rabbitmq-erlang.repo
[root@node1 ~]# [rabbitmq-erlang]
name=rabbitmq-erlang
baseurl=https://dl.bintray.com/rabbitmq/rpm/erlang/20/el/7
gpgcheck=1
gpgkey=https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc
repo_gpgcheck=0
enabled=1

[root@node1 ~]# yum -y install erlang socat

然後安裝 RabbitMQ Server:

[root@node1 ~]# mkdir -p ~/download && cd ~/download
[root@node1 download]# wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/rabbitmq-server-3.6.10-1.el7.noarch.rpm
[root@node1 download]# rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
[root@node1 download]# rpm -Uvh rabbitmq-server-3.6.10-1.el7.noarch.rpm

卸載 RabbitMQ 命令:

[root@node1 ~]# rpm -e rabbitmq-server-3.6.10-1.el7.noarch

安裝好之後,就可以啟動 RabbitMQ Server 了:

[root@node1 download]# systemctl start rabbitmq-server

也可以添加到系統服務中啟動:

[root@node1 download]# systemctl enable rabbitmq-server
Created symlink from /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service to /usr/lib/systemd/system/rabbitmq-server.service.

啟動成功之後,我們可以查看下 RabbitMQ Server 的狀態:

[root@node1 download]# systemctl status rabbitmq-server
● rabbitmq-server.service - RabbitMQ broker
   Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled)
   Active: active (running) since 五 2018-04-27 04:44:31 CEST; 3min 27s ago
  Process: 17216 ExecStop=/usr/sbin/rabbitmqctl stop (code=exited, status=0/SUCCESS)
 Main PID: 17368 (beam.smp)
   Status: "Initialized"
   CGroup: /system.slice/rabbitmq-server.service
           ├─17368 /usr/lib64/erlang/erts-9.3/bin/beam.smp -W w -A 64 -P 1048576 -t 5000000 -stbt db -zdbbl 32000 -K true -- -root /usr/lib64/erlang -progname erl -- -home /var/lib/rabbitmq -- -pa /usr...
           ├─17521 /usr/lib64/erlang/erts-9.3/bin/epmd -daemon
           ├─17655 erl_child_setup 1024
           ├─17675 inet_gethost 4
           └─17676 inet_gethost 4

4月 27 04:44:30 node1 rabbitmq-server[17368]: RabbitMQ 3.6.10. Copyright (C) 2007-2017 Pivotal Software, Inc.
4月 27 04:44:30 node1 rabbitmq-server[17368]: ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/
4月 27 04:44:30 node1 rabbitmq-server[17368]: ##  ##
4月 27 04:44:30 node1 rabbitmq-server[17368]: ##########  Logs: /var/log/rabbitmq/[email protected]
4月 27 04:44:30 node1 rabbitmq-server[17368]: ######  ##        /var/log/rabbitmq/[email protected]
4月 27 04:44:30 node1 rabbitmq-server[17368]: ##########
4月 27 04:44:30 node1 rabbitmq-server[17368]: Starting broker...
4月 27 04:44:31 node1 rabbitmq-server[17368]: systemd unit for activation check: "rabbitmq-server.service"
4月 27 04:44:31 node1 systemd[1]: Started RabbitMQ broker.
4月 27 04:44:31 node1 rabbitmq-server[17368]: completed with 0 plugins.
[root@node1 download]# systemctl enable rabbitmq-server
ln -s '/usr/lib/systemd/system/rabbitmq-server.service' '/etc/systemd/system/multi-user.target.wants/rabbitmq-server.service'

然後啟動 RabbitMQ Web 管理控制台:

[root@node1 download]# rabbitmq-plugins enable rabbitmq_management
The following plugins have been enabled:
  amqp_client
  cowlib
  cowboy
  rabbitmq_web_dispatch
  rabbitmq_management_agent
  rabbitmq_management

Applying plugin configuration to rabbit@node1... started 6 plugins.

RabbitMQ Server 預設guest用戶,只能localhost地址訪問,我們還需要創建管理用戶:

[root@node1 download]# rabbitmqctl add_user admin admin123 && 
rabbitmqctl set_user_tags admin administrator && 
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"

然後添加防火牆運行訪問的埠:

[root@node1 download]# firewall-cmd --zone=public --permanent --add-port=4369/tcp && 
firewall-cmd --zone=public --permanent --add-port=25672/tcp && 
firewall-cmd --zone=public --permanent --add-port=5671-5672/tcp && 
firewall-cmd --zone=public --permanent --add-port=15672/tcp && 
firewall-cmd --zone=public --permanent --add-port=61613-61614/tcp && 
firewall-cmd --zone=public --permanent --add-port=1883/tcp && 
firewall-cmd --zone=public --permanent --add-port=8883/tcp
success

重新啟動防火牆:

[root@node1 download]# firewall-cmd --reload
success

上面這些做完了,RabbitMQ 單機版的部署也完成了,我們可以瀏覽器訪問``:

將上面的搭建過程,在node2伺服器上,再做重覆一邊。

3. RabbitMQ Server 高可用集群相關概念

設計集群的目的

  • 允許消費者和生產者在 RabbitMQ 節點崩潰的情況下繼續運行。
  • 通過增加更多的節點來擴展消息通信的吞吐量。

集群配置方式

  • cluster:不支持跨網段,用於同一個網段內的區域網;可以隨意的動態增加或者減少;節點之間需要運行相同版本的 RabbitMQ 和 Erlang。
  • federation:應用於廣域網,允許單台伺服器上的交換機或隊列接收發佈到另一臺伺服器上交換機或隊列的消息,可以是單獨機器或集群。federation 隊列類似於單向點對點連接,消息會在聯盟隊列之間轉發任意次,直到被消費者接受。通常使用 federation 來連接 internet 上的中間伺服器,用作訂閱分發消息或工作隊列。
  • shovel:連接方式與 federation 的連接方式類似,但它工作在更低層次。可以應用於廣域網。

節點類型

  • RAM node:記憶體節點將所有的隊列、交換機、綁定、用戶、許可權和 vhost 的元數據定義存儲在記憶體中,好處是可以使得像交換機和隊列聲明等操作更加的快速。
  • Disk node:將元數據存儲在磁碟中,單節點系統只允許磁碟類型的節點,防止重啟 RabbitMQ 的時候,丟失系統的配置信息。

問題說明:RabbitMQ 要求在集群中至少有一個磁碟節點,所有其他節點可以是記憶體節點,當節點加入或者離開集群時,必須要將該變更通知到至少一個磁碟節點。如果集群中唯一的一個磁碟節點崩潰的話,集群仍然可以保持運行,但是無法進行其他操作(增刪改查),直到節點恢復。
解決方案:設置兩個磁碟節點,至少有一個是可用的,可以保存元數據的更改。

Erlang Cookie 是保證不同節點可以相互通信的密鑰,要保證集群中的不同節點相互通信必須共用相同的 Erlang Cookie。具體的目錄存放在/var/lib/rabbitmq/.erlang.cookie

說明:這就要從 rabbitmqctl 命令的工作原理說起,RabbitMQ 底層是通過 Erlang 架構來實現的,所以 rabbitmqctl 會啟動 Erlang 節點,並基於 Erlang 節點來使用 Erlang 系統連接 RabbitMQ 節點,在連接過程中需要正確的 Erlang Cookie 和節點名稱,Erlang 節點通過交換 Erlang Cookie 以獲得認證。

鏡像隊列

RabbitMQ 的 Cluster 集群模式一般分為兩種,普通模式和鏡像模式。

  • 普通模式:預設的集群模式,以兩個節點(rabbit01、rabbit02)為例來進行說明。對於 Queue 來說,消息實體只存在於其中一個節點 rabbit01(或者 rabbit02),rabbit01 和 rabbit02 兩個節點僅有相同的元數據,即隊列的結構。當消息進入 rabbit01 節點的 Queue 後,consumer 從 rabbit02 節點消費時,RabbitMQ 會臨時在 rabbit01、rabbit02 間進行消息傳輸,把 A 中的消息實體取出並經過 B 發送給 consumer。所以 consumer 應儘量連接每一個節點,從中取消息。即對於同一個邏輯隊列,要在多個節點建立物理 Queue。否則無論 consumer 連 rabbit01 或 rabbit02,出口總在 rabbit01,會產生瓶頸。當 rabbit01 節點故障後,rabbit02 節點無法取到 rabbit01 節點中還未消費的消息實體。如果做了消息持久化,那麼得等 rabbit01 節點恢復,然後才可被消費;如果沒有持久化的話,就會產生消息丟失的現象。
  • 鏡像模式:將需要消費的隊列變為鏡像隊列,存在於多個節點,這樣就可以實現 RabbitMQ 的 HA 高可用性。作用就是消息實體會主動在鏡像節點之間實現同步,而不是像普通模式那樣,在 consumer 消費數據時臨時讀取。缺點就是,集群內部的同步通訊會占用大量的網路帶寬。

鏡像隊列實現了 RabbitMQ 的高可用性(HA),具體的實現策略如下所示:

ha-mode ha-params 功能
all 鏡像隊列將會在整個集群中複製。當一個新的節點加入後,也會在這 個節點上複製一份。
exactly count 鏡像隊列將會在集群上複製 count 份。如果集群數量少於 count 時候,隊列會複製到所有節點上。如果大於 Count 集群,有一個節點 crash 後,新進入節點也不會做新的鏡像。
nodes node name 鏡像隊列會在 node name 中複製。如果這個名稱不是集群中的一個,這不會觸發錯誤。如果在這個 node list 中沒有一個節點線上,那麼這個 queue 會被聲明在 client 連接的節點。

實例列舉:

queue_args("x-ha-policy":"all") //定義字典來設置額外的隊列聲明參數
channel.queue_declare(queue="hello-queue",argument=queue_args)

如果需要設定特定的節點(以rabbit@localhost為例),再添加一個參數:

queue_args("x-ha-policy":"nodes",
           "x-ha-policy-params":["rabbit@localhost"])
channel.queue_declare(queue="hello-queue",argument=queue_args)

可以通過命令行查看那個主節點進行了同步:

$ rabbitmqctl list_queue name slave_pids synchronised_slave_pids

以上內容主要參考:RabbitMQ 分散式集群架構

4. 搭建 RabbitMQ Server 高可用集群

理解了上面的概念之後,我們再搭建 RabbitMQ Server 高可用集群,就非常容易了。

預設.erlang.cookie文件是隱藏的,ls命令並不能查看,你也可以手動搜索下文件:

[root@node1 ~]# find / -name ".erlang.cookie"
/var/lib/rabbitmq/.erlang.cookie
[root@node1 ~]# cat /var/lib/rabbitmq/.erlang.cookie
LBOTELUJAMXDMIXNTZMB

node1伺服器中的.erlang.cookie文件,拷貝到node2伺服器上:

[root@node1 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq

先停止運行節點,然後以後臺方式啟動 RabbitMQ Server(node1node2分別執行):

[root@node1 ~]# rabbitmqctl stop
[root@node1 ~]# rabbitmq-server -detached

然後我們以node1作為集群中心,在node2上執行加入集群中心命令(節點類型為磁碟節點):

[root@node1 ~]# rabbitmqctl stop_app
[root@node1 ~]# rabbitmqctl reset 
[root@node1 ~]# rabbitmqctl join_cluster rabbit@node1
//預設是磁碟節點,如果是記憶體節點的話,需要加--ram參數
[root@node1 ~]# rabbitmqctl start_app

查看集群的狀態(包含node1node2節點):

[root@node1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@node1
[{nodes,[{disc,[rabbit@node1,rabbit@node2]}]},
 {running_nodes,[rabbit@node2,rabbit@node1]},
 {cluster_name,<<"rabbit@node1">>},
 {partitions,[]},
 {alarms,[{rabbit@node2,[]},{rabbit@node1,[]}]}]

我們可以從 RabbitMQ Web 管理界面,看到集群的信息:

5. 搭建 HAProxy 負載均衡

HAProxy 是一個免費的負載均衡軟體,可以運行於大部分主流的 Linux 操作系統上。

HAProxy 提供了 L4(TCP) 和 L7(HTTP) 兩種負載均衡能力,具備豐富的功能。HAProxy 的社區非常活躍,版本更新快速(最新穩定版 1.7.2 於 2017/01/13 推出)。最關鍵的是,HAProxy 具備媲美商用負載均衡器的性能和穩定性。它當前不僅僅是免費負載均衡軟體的首選,更幾乎成為了唯一選擇。

因為 RabbitMQ 本身不提供負載均衡,下麵我們就搭建 HAProxy,用作 RabbitMQ 集群的負載均衡。

HAProxy 安裝在node1伺服器上,安裝命令:

[root@node1 ~]# rpm -ivh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm//
[root@node1 ~]# yum -y install haproxy

配置 HAProxy:

[root@node1 ~]# cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
[root@node1 ~]# vi /etc/haproxy/haproxy.cfg

將下麵的配置添加到/etc/haproxy/haproxy.cfg文件中:

global
    log     127.0.0.1  local0 info
    log     127.0.0.1  local1 notice
    daemon
    maxconn 4096

defaults
    log     global
    mode    tcp
    option  tcplog
    option  dontlognull
    retries 3
    option  abortonclose
    maxconn 4096
    timeout connect  5000ms
    timeout client  3000ms
    timeout server  3000ms
    balance roundrobin

listen private_monitoring
    bind    0.0.0.0:8100
    mode    http
    option  httplog
    stats   refresh  5s
    stats   uri  /stats
    stats   realm   Haproxy
    stats   auth  admin:admin

listen rabbitmq_admin
    bind    0.0.0.0:8102
    server  node1 node1:15672
    server  node2 node2:15672

listen rabbitmq_cluster
    bind    0.0.0.0:8101
    mode    tcp
    option  tcplog
    balance roundrobin
    server  node1  node1:5672  check  inter  5000  rise  2  fall  3
    server  node2  node2:5672  check  inter  5000  rise  2  fall  3

然後啟動 HAProxy:

[root@node1 ~]# haproxy -f /etc/haproxy/haproxy.cfg

外部訪問的話,需要關閉下防火牆:

[root@node1 ~]# systemctl disable firewalld.service
rm '/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service'
rm '/etc/systemd/system/basic.target.wants/firewalld.service'
[root@node1 ~]# systemctl stop firewalld.service

HAProxy 配置了三個地址:

  • http://node1:8100/stats:HAProxy 負載均衡信息地址,賬號密碼:admin/admin
  • http://node1:8101:RabbitMQ Server Web 管理界面(基於負載均衡)。
  • http://node1:8102:RabbitMQ Server 服務地址(基於負載均衡)。

通過訪問http://node1:8100/stats,查看 HAProxy 負載均衡信息:

參考資料:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • (1)從線程的時效來看:分為同步和非同步 同步:多個任務情況下,一個任務A執行結束,才可以執行另一個任務B。只存在一個線程。 非同步:多個任務情況下,一個任務A正在執行,同時可以執行另一個任務B。任務B不用等待任務A結束才執行。存在多條線程。 (2)從線程的執行來看:分為串列隊列和並行隊列 串列隊列:串 ...
  • 1、介紹一下標準的CSS的盒子模型?與低版本IE的盒子模型有什麼不同的? 標準盒子模型:寬度=內容的寬度(content)+ border + padding + margin低版本IE盒子模型:寬度=內容寬度(content+border+padding)+ margin 2、box-sizing ...
  • JavaScript中基本數據類型和引用數據類型的區別 這是我引用別人的 覺得很好 1、基本數據類型和引用數據類型 ECMAScript包括兩個不同類型的值:基本數據類型和引用數據類型。 基本數據類型指的是簡單的數據段,引用數據類型指的是有多個值構成的對象。 當我們把變數賦值給一個變數時,解析器首先 ...
  • 動畫調用語法 animation: bounceIn 0.3s ease 0.2s 1 both; 按順序解釋參數: 動畫名稱 如:bounceIn 一周期所用時間 如:0.3s 速度曲線 如:ease 值 描述 linear 動畫從頭到尾的速度是相同的。 ease 預設。動畫以低速開始,然後加快, ...
  • Tabs {{tab.type}} ...
  • 第三天:讓簡歷有點色彩 這一節課是來初步瞭解什麼是CSS,掌握基本的CSS概念,語法,學習如何設置一些簡單的樣式。 好記性不如爛筆頭,開始: 字體: font-style:設置字體傾斜。 font-weight: 設置文字的粗體大小。 text-transform :設置要轉換的字體。可以轉換成大小 ...
  • 區塊鏈無疑是現在最火熱的技術,自從比特幣火了,其背後的技術——區塊鏈也得到了史無前例的追捧,這些年,各個行業都在實踐落地以搶占先機。 今天推薦一本區塊鏈技術的學習書籍—— ,除了原理之外知識之外,更多的是如何實戰把區塊鏈技術真正落地應用,也能幫助打開區塊鏈誤區,拓展知識面。 本書介紹 • 國內區塊鏈 ...
  • 中介者模式是關於數據交互的設計模式,該模式的核心是一個中介者對象,負責協調一系列對象之間的不同的數據請求,這一系列對象成為同事類。如房產中介(簡直不想提它),買房的賣房的,租房的放租的都到房產中介那裡去登記。如果有賣房的就會通知買房的去買房,如果有放租的就會通知租房的去租房。所有的事物都是通過中介進 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...