目錄

  • RabbitMQ項目使用集羣的好處
  • 1. 擴展規模
  • 2. 數據冗餘
  • 3. 高可用
  • RabbitMQ集羣搭建
  • RabbitMQ集羣原理
  • RabbitMQ集羣搭建步驟
  • 單節點安裝Rabbitmq
  • 複製Erlang cookie
  • 集羣鏡像隊列原理
  • 集羣鏡像隊列設置方法
  • Definition:策略定義
  • 設置鏡像隊列策略案例:
  • 將鏡像配置到集羣中的所有節點
  • HAproxy+ Keepalived高可用集羣搭建
  • 實現高可用的方式
  • HAProxy簡介
  • HAProxy配置方法
  • Keepalived簡介
  • keepalived配置(兩個節點都需要)
  • 總結
  • RabbitMQ集羣間通信
  • RabbitMQ集羣間通信方法
  • Federation(聯邦)
  • ◆Shovel (鏟子)
  • 總結
  • 經驗和小結
  • 實際開發經驗
  • 小結

RabbitMQ項目使用集羣的好處

1. 擴展規模

◆ 般的基礎架構中,單機擴容(Scale-Up)很難實現
◆ 需要擴容時儘量使用擴展數量實現(Scale-Out)
◆ RabbitMQ集羣可以方便地通過Scale-Out擴展規模

2. 數據冗餘

◆ 對於單節點RabbitMQ,如果節點宕機,內存數據丟失
◆ 對於單節點RabbitMQ,如果節點損壞,磁盤數據丟失
◆ RabbitMQ集羣可以通過鏡像隊列,將數據冗餘至多個節點.

3. 高可用

◆ 如果單節點RabbitMQ宕機,服務不可用
◆ RabbitMQ集羣可以通過負載均衡,將請求轉移至可用節點

RabbitMQ集羣搭建

RabbitMQ集羣原理

◆ 多個RabbitMQ單節點,經過配置組成RabbitMQ集羣

◆ 集羣節點之間共享元數據,不共享隊列數據(默認)

◆ RabbitMQ節點數據互相轉發,客户端通過單一節點可以訪問所有數據.

Windows decker desktop構建rabbitMq的容器_#學習

RabbitMQ集羣搭建步驟

◆ 設置主機名或host,使得節點之間可以通過名稱訪問
◆ 安裝RabbitMQ單節點
◆ 複製Erlang cookie
◆ 啓動RabbitMQ並組成集羣

單節點安裝Rabbitmq

  1. 設置主機名稱
    hostnamectl set-hostname master.localdomain
  2. 在hosts文件中,前兩行里加入主機名稱
    vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 master
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6 master
  1. 安裝epel
    sudo yum install epel-release -y
  2. 安裝erlang
    sudo yum install erlang -y
  3. 安裝socat
    yum install socat -y
  4. 安裝wget
    yum install wget -y
  5. 下載rabbitmq安裝包
mkdir -p /apps/rabbitMQ/
cd /apps/rabbitMQ/
wget  https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.8/rabbitmq-server-3.8.8-1.el8.noarch.rpm
  1. 導入rabbitmq密鑰
    rpm -import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
  2. 安裝rabbitmq
    rpm -ivh --nodeps rabbitmq-server-3.8.8-1.el8.noarch.rpm
    rpm -ivh rabbitmq-server-3.8.8-1.el8.noarch.rpm
  3. 管理rabbitmq服務
    systemctl start rabbitmq-server
    systemctl stop rabbitmq-server
    systemctl status rabbitmq-server
  4. 啓用管控台插件
    rabbitmq-plugins enable rabbitmq_management
  5. 關閉系統防火牆
    systemctl stop firewalld.service
    systemctl disable firewalld.service
  6. 添加測試賬户
rabbitmqctl add_user test test
rabbitmqctl set_user_tags test administrator
rabbitmqctl set_permissions -p / test ".*" ".*" ".*"

配置四台主機通過主機名訪問:

vim /etc/hosts

192.168.166.134 master
192.168.166.135 salve1
192.168.166.136 salve2
192.168.166.137 salve3

複製Erlang cookie

  1. 需要停掉服務器的rabbitMQ的服務(如果沒有停掉的話,Erlang的cookie是再被佔用的)
    systemctl stop rabbitmq-server
  2. 修改.erlang.cookie權限
    cat /var/lib/rabbitmq/.erlang.cookie
    chmod 777 /var/lib/rabbitmq/.erlang.cookie
  3. 將主節點的.erlang.cookie文件傳輸至集羣所有節點
    scp /var/lib/rabbitmq/.erlang.cookie root@salve1:/var/lib/rabbitmq/.erlang.cookie
    scp /var/lib/rabbitmq/.erlang.cookie root@salve2:/var/lib/rabbitmq/.erlang.cookie
    scp /var/lib/rabbitmq/.erlang.cookie root@salve3:/var/lib/rabbitmq/.erlang.cookie
  4. 復原.erlang.cookie權限
    chmod 400 /var/lib/rabbitmq/.erlang.cookie
  5. 加入集羣
# 所有節點啓動rabbitmq
systemctl start rabbitmq-server

# 在非主節點上執行以下命令
rabbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@master
rabbitmqctl start_app
  1. 打開master管控台
    http://192.168.166.134:15672 可以看到所有節點的狀態

以上RabbitMQ集羣解決了 高可用的 問題

集羣鏡像隊列原理

Windows decker desktop構建rabbitMq的容器_erlang_02

集羣鏡像隊列設置方法

◆ 搭建集羣
◆ 使用set_ policy 命令設置鏡像隊列策略
rabbitmqctl set_ policy [-p Vhost] Name Pattern Definition [Priority]
rabbitmqctl set_ policy Vhost 策咯名稱 正則表達式 策略定義 優先級

Definition:策略定義

◆ ha-mode:指明鏡像隊列的模式
all:表示在集羣中所有的節點上進行鏡像
exactly:表示在指定個數的節點上進行鏡像,節點的個數由ha-params指定
nodes:表示在指定的節點上進行鏡像,節點名稱通過ha-params指定

◆ ha-params: ha-mode模式需要用到的參數
◆ ha-svnc-mode:進行隊列中消息的同步方式,有效值為automatic和manual

設置鏡像隊列策略案例:

◆ 匹配所有隊列,並將鏡像配置到集羣中的所有節點
rabbitmqctl set_policy ha-all “^” ‘{“ha-mode”:“all”}’

◆ 名稱以"two"開始的隊列鏡像到羣集中的任意兩個節點
rabbitmqctl set_policy ha-two “^two.” ‘{“ha-mode” :" exactly" ,“ha-params”:2,“ha-sync-mode”:" automatic}’

◆ 以" node"開頭的隊列鏡像到集羣中的特定節點
rabbitmqctl set_policy ha-nodes “^ nodes.” ‘{“ha-mode”:" nodes" ,“ha-params” :[“rabbit@nodeA”, “rabbit@nodeB”]}’

將鏡像配置到集羣中的所有節點

我們選擇使用匹配所有隊列
在主節點中:
rabbitmqctl set_policy ha-all “^” ‘{“ha-mode”:“all”}’

設置完後,會將隊列數據保存在多個節點結果如下

Windows decker desktop構建rabbitMq的容器_#rabbitmq_03


Windows decker desktop構建rabbitMq的容器_高可用_04


Windows decker desktop構建rabbitMq的容器_#學習_05

以上RabbitMQ集羣+鏡像隊列解決了 數據冗餘的 問題

HAproxy+ Keepalived高可用集羣搭建

HAproxy+ Keepalived直接在master和salve1結點上搭建

實現高可用的方式

◆ 客户端負載均衡

Windows decker desktop構建rabbitMq的容器_#學習_06

客户端負載均衡設置方法
直接在SpringBoot配置文件中設置多個地址
spring.rabbitmq.addresses= 127.0.0.1, 127.0.0.2, 127.0.0.3

◆ 服務端負載均衡

Windows decker desktop構建rabbitMq的容器_erlang_07

HAProxy簡介

◆ HAProxy是一款提供高可用性、負載均衡以及基於TCP和HTTP應用的代理軟件
◆ HAProxy適用於那些負載較大的web站點
◆ HAProxy可以支持數以萬計的併發連接.

HAProxy配置方法

可以新建一台虛擬機進行搭建,我就直接在master節點上配置HAProxy
◆ 安裝HaProxy
yum install haproxy -y

◆ 編輯hosts,使得haproxy能夠通過主機名訪問集羣節點
vi /etc/hosts
192.168.166.134 master
192.168.166.135 salve1
192.168.166.136 salve2
192.168.166.137 salve3

◆ 編輯haproxy配置文件
vi /etc/haproxy/haproxy.cfg

global
	# 日誌輸出配置、所有日誌都記錄在本機,通過 local0 進行輸出
	log 127.0.0.1 local0 info
	# 最大連接數
	maxconn 4096
	# 守護模式
	daemon
# 默認配置
defaults
	# 應用全局的日誌配置
	log global
	# 使用4層代理模式,7層代理模式則為"http"
	mode tcp
	# 日誌類別
	option tcplog
	# 不記錄健康檢查的日誌信息
	option dontlognull
	# 3次失敗則認為服務不可用
	retries 3
	# 每個進程可用的最大連接數
	maxconn 2000
	# 連接超時
	timeout connect 5s
	# 客户端超時
	timeout client 120s
	# 服務端超時
	timeout server 120s

# 綁定配置
listen rabbitmq_cluster
	# 綁定端口,需要不被佔用的端口
	bind :5671
	# 配置TCP模式
	mode tcp
	# 採用加權輪詢的機制進行負載均衡
	balance roundrobin
	# RabbitMQ 集羣節點配置
	server master master:5672 check inter 5000 rise 2 fall 3 weight 1
	server salve1 salve1:5672 check inter 5000 rise 2 fall 3 weight 1
	server salve2 salve2:5672 check inter 5000 rise 2 fall 3 weight 1
	server salve3 salve3:5672 check inter 5000 rise 2 fall 3 weight 1
# 配置監控頁面
listen monitor
	bind *:8100
	mode http
	option httplog
	stats enable
	stats uri /rabbitmq
	stats refresh 5s

◆ 設置seLinux(需要開放Linux的一些限制)
sudo setsebool -P haproxy_connect_any=1

◆ 關閉防火牆
systemctl stop firewalld.service
systemctl disable firewalld.service

◆ 啓動haproxy
systemctl start haproxy

◆ 進入web監控界面

ip:8100/rabbitmq

http://192.168.166.134:8100/rabbitmq

Windows decker desktop構建rabbitMq的容器_erlang_08

問題:HaProxy掛了怎麼辦?
◆ 再用一層負載均衡,不能解決問題,因為最後一層機器永遠有風險
◆ 使用Virtual IP (VIP, 虛擬IP) 解決問題

Keepalived簡介

◆ 高性能的服務器高可用或熱備解決方案

◆ 主要來防止服務器單點故障的發生問題

◆ 以VRRP協議為實現基礎,用VRRP協議來實現高可用性

Windows decker desktop構建rabbitMq的容器_#分佈式_09

keepalived配置(兩個節點都需要)

  1. 安裝keepalived
    yum install keepalived -y
  2. 編輯keepalived配置文件
    vi /etc/keepalived/keepalived.conf

主機配置文件:(主節點)

! Configuration File for keepalived
global_defs {
	router_id master
	vrrp_skip_check_adv_addr
	vrrp_strict
	vrrp_garp_interval 0
	vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
	script "/etc/keepalived/haproxy_check.sh" ##執行腳本位置
	interval 2 ##檢測時間間隔
	weight -20 ##如果條件成立則權重減20
}
vrrp_instance VI_1 {
	# 配置需要綁定的VIP和本機的IP
	state MASTER
	interface ens33
	virtual_router_id 28
	# 本機IP
	mcast_src_ip 192.168.166.134
	priority 100
	advert_int 1
	# 通信之間設置的用户名和密碼
	authentication {
		auth_type PASS
		auth_pass 123456
	}
	# 虛擬IP
	virtual_ipaddress {
		192.168.166.238
	}
	# 健康檢查
	track_script {
		chk_haproxy
	}
}

熱備機配置文件:(從節點)

global_defs {
	router_id salve1
	vrrp_skip_check_adv_addr
	vrrp_strict
	vrrp_garp_interval 0
	vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
	script "/etc/keepalived/haproxy_check.sh" ##執行腳本位置
	interval 2 ##檢測時間間隔
	weight -20 ##如果條件成立則權重減20
}
vrrp_instance VI_1 {
	state BACKUP
	interface ens33
	virtual_router_id 28
	mcast_src_ip 192.168.166.135
	priority 50
	advert_int 1
	authentication {
		auth_type PASS
		auth_pass 123456
 	}
	virtual_ipaddress {
		192.168.166.238
	}
	track_script {
		chk_haproxy
	}
}
  1. 健康檢測腳本
    vi /etc/keepalived/haproxy_check.sh
#!/bin/bash
COUNT=`ps -C haproxy --no-header |wc -l`
if [ $COUNT -eq 0 ];then
	systemctl start haproxy
	sleep 2
	if [ `ps -C haproxy --no-header |wc -l` -eq 0 ];then
		systemctl stop keepalived
	fi
fi
  1. 修改健康檢測腳本執行權限
    chmod +x /etc/keepalived/haproxy_check.sh
  2. 啓動keepalived
    systemctl start keepalived
    啓動後發現主節點ip中多了一個虛擬ip,而從節點沒有
    主節點ip:
  3. Windows decker desktop構建rabbitMq的容器_高可用_10

從節點ip:

Windows decker desktop構建rabbitMq的容器_#學習_11

  1. 做故障轉移實驗時,關閉keepalived即可
    systemctl stop keepalived
    關閉主節後發現從節點ip中多了一個虛擬ip,而主節點虛擬ip消失了
    主節點ip:

從節點ip:

Windows decker desktop構建rabbitMq的容器_#學習_12

總結

◆ RabbitMQ集羣 + 鏡像隊列 + HAproxy + Keepalived可以同時解決RabbitMQ的可擴展、數據冗餘、高可用.
◆ 在使用客户端負載均衡時,可以省去HAproxy+ Keepalived

RabbitMQ集羣間通信

問題:如果兩個集羣間處於異地,需要通訊會有以下問題
◆ 由於異地網絡延時,異地RabbitMQ和業務應用之間很難建立網絡連接
◆ 由於異地網絡延時,異地RabbitMQ之間很難建立集羣
◆ 此時如果異地RabbitMQ之間需要共享消息,需要使用集羣間通信機制

RabbitMQ集羣間通信方法

Federation(聯邦)

Federation簡介:
◆ 通過AMQP協議,使用一個內部交換機,讓原本發送到一個集羣的消息轉發至另一個集羣
◆ 消息可以從交換機轉發至交換機,也可以由隊列轉發至隊列
◆ 消息可以單向轉發,也可以雙向轉發

Federation設置方法
◆ 啓用Federation插件
rabbitmq-plugins enable rabbitmq_federation_management
◆ 使用管控台具體配置Federation

具體使用的時候再查文檔

◆Shovel (鏟子)

Federation簡介:
◆ Shovel可以持續地從一 個broker拉取消息轉發至另一個broker
◆ Shovel的使用較為靈活,可以配置從隊列至交換機從隊列至隊列,從交換機至交換機

Shovel設置方法
◆ 啓用插件
rabbitmq-plugins enable rabbitmq_ shovel_ management
◆ 使用管控台具體配置Shovel

具體使用的時候再查文檔

總結

◆ Federation和Shovel都是在broker之間轉發/共享消息的方法
◆ Federation只能在交換機之間或者隊列之間轉發消息
◆ Shovel更加靈活,可以在交換機和隊列之間轉發消息

經驗和小結

實際開發經驗

◆ 體系架構升級的根本原因是需求
◆ 不要盲目升級更高級的架構,更高級的架構意味着對運維有更高的要求
◆ 多思考架構拓撲,形成更好的架構思維

小結

◆ 為了追求規模的擴展性,搭建RabbitMQ集羣
◆ 為了追求數據的冗餘,使用RabbitMQ集羣鏡像隊列
◆ 為了RabbitMQ服務高可用,使用了服務端的負載均衡技術
◆ 為了跨地域傳送消息,學習了跨broker通信技術