本文介紹 RabbitMQ 集群的 Docker 化部署邪铲,最開始是想通過 DockerSwarm 方式來部署的供汛,但是 RabbitMQ 節(jié)點(diǎn)加入集群時(shí)一直失敗,在網(wǎng)上找了很多辦法东帅,始終沒有解決這個(gè)問題咆爽,無奈只能放棄霞赫。所以最終采用配置 hosts 文件方式來保證節(jié)點(diǎn)之間的通信腮介,下面來進(jìn)行詳細(xì)說明。
部署環(huán)境
- 系統(tǒng):CentOS8
- 兩臺(tái)服務(wù)器:10.1.1.1/10.1.1.2
docker-compose 文件
version: '3'
services:
rabbit1:
container_name: rabbit1
image: rabbitmq:3.7-management-alpine
restart: always
hostname: rabbit1
extra_hosts:
- "rabbit1:10.1.1.1"
- "rabbit2:10.1.1.2"
environment:
- RABBITMQ_ERLANG_COOKIE=MY_COOKIE
- RABBITMQ_DEFAULT_USER=MY_USER
- RABBITMQ_DEFAULT_PASS=MY_PASS
ports:
- "4369:4369"
- "5671:5671"
- "5672:5672"
- "15671:15671"
- "15672:15672"
- "25672:25672"
這樣绩脆,10.1.1.1 上的 docker-compose 文件就寫好了萤厅,部署另一臺(tái)時(shí)橄抹,只要將 rabbit1
改成 rabbit2
就可以了靴迫。如果是更多臺(tái)服務(wù)器的話,也是同樣的道理楼誓,將 IP 配置到 extra_hosts
參數(shù)下即可玉锌。
啟動(dòng)服務(wù)
在兩臺(tái)服務(wù)器上分別執(zhí)行:
# docker-compose up -d
加入集群
如果將 rabbit1
作為主節(jié)點(diǎn)的話,需要在 rabbit2
上執(zhí)行命令疟羹,將其加入到集群主守,如下:
# docker exec -it rabbit2 /bin/bash
rabbit2# rabbitmqctl stop_app
rabbit2# rabbitmqctl reset
rabbit2# rabbitmqctl join_cluster rabbit@rabbit1
rabbit2# rabbitmqctl start_app
默認(rèn)情況下禀倔,RabbitMQ 啟動(dòng)后是磁盤節(jié)點(diǎn),如果想以內(nèi)存節(jié)點(diǎn)方式加入参淫,可以加 --ram
參數(shù)救湖。
如果想要修改節(jié)點(diǎn)類型,可以使用命令:
# rabbitmqctl change_cluster_node_type disc(ram)
修改節(jié)點(diǎn)類型之前需要先 rabbitmqctl stop_app
涎才。
通過下面命令來查看集群狀態(tài):
# rabbitmqctl cluster_status
注意鞋既,由于 RAM 節(jié)點(diǎn)僅將內(nèi)部數(shù)據(jù)庫表存儲(chǔ)在內(nèi)存中,因此在內(nèi)存節(jié)點(diǎn)啟動(dòng)時(shí)必須從其他節(jié)點(diǎn)同步這些數(shù)據(jù)耍铜,所以一個(gè)集群必須至少包含一個(gè)磁盤節(jié)點(diǎn)邑闺。
HAProxy 負(fù)載均衡
ha 同樣采用 Docker 方式來部署,先看一下 haproxy.cfg 配置文件:
# Simple configuration for an HTTP proxy listening on port 80 on all
# interfaces and forwarding requests to a single backend "servers" with a
# single server "server1" listening on 127.0.0.1:8000
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 5000ms
timeout server 5000ms
listen rabbitmq_cluster
bind 0.0.0.0:5677
option tcplog
mode tcp
balance leastconn
server rabbit1 10.1.1.1:5672 weight 1 check inter 2s rise 2 fall 3
server rabbit2 10.2.2.2:5672 weight 1 check inter 2s rise 2 fall 3
listen http_front
bind 0.0.0.0:8002
stats uri /haproxy?stats
listen rabbitmq_admin
bind 0.0.0.0:8001
server rabbit1 10.1.1.1:15672
server rabbit2 10.1.1.2:15672
再看一下 docker-compose 文件:
version: '3'
services:
haproxy:
container_name: rabbit-haproxy
image: haproxy
restart: always
hostname: haproxy
network_mode: rabbitmq_default
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
ports:
- "5677:5677"
- "8001:8001"
- "8002:8002"
啟動(dòng)之后棕兼,就可以通過 ha 的地址來訪問 RabbitMQ 集群管理頁面了陡舅。
如果公司內(nèi)部有現(xiàn)成的負(fù)載均衡,比如 LVS伴挚,那么也可以省略這一步靶衍。
其實(shí)到這里,集群就可以正常使用了章鲤,但還有很重要的一點(diǎn)需要做些說明摊灭。
集群模式
普通模式
- 對(duì)于 Queue 來說,消息實(shí)體只存在于其中一個(gè)節(jié)點(diǎn)败徊,A帚呼、B 兩個(gè)節(jié)點(diǎn)僅有相同的元數(shù)據(jù),即隊(duì)列結(jié)構(gòu)皱蹦。
- 當(dāng)消息進(jìn)入 A 節(jié)點(diǎn)的隊(duì)列中后煤杀,消費(fèi)者從 B 節(jié)點(diǎn)拉取時(shí),RabbitMQ 會(huì)臨時(shí)在 A沪哺、B 間進(jìn)行消息傳輸沈自,把 A 中的消息實(shí)體取出并經(jīng)過 B 發(fā)送給消費(fèi)者。
- 所以辜妓,消費(fèi)者應(yīng)盡量連接每一個(gè)節(jié)點(diǎn)枯途,從中取消息。即對(duì)于同一個(gè)邏輯隊(duì)列籍滴,要在多個(gè)節(jié)點(diǎn)建立物理隊(duì)列酪夷,否則,無論消費(fèi)者連 A 或者連 B孽惰,出口總在 A晚岭,會(huì)產(chǎn)生瓶頸。
- 該模式還存在一個(gè)問題就是當(dāng) A 節(jié)點(diǎn)故障后勋功,B 節(jié)點(diǎn)無法取到 A 節(jié)點(diǎn)中還未消費(fèi)的消息實(shí)體坦报。
- 如果做了消息持久化库说,那么得等 A 節(jié)點(diǎn)恢復(fù),才可被消費(fèi)片择;如果沒有持久化的話潜的,消息會(huì)丟失。
鏡像模式
- 該模式解決了上述問題字管,其和普通模式不同之處在于夏块,消息實(shí)體會(huì)主動(dòng)在鏡像節(jié)點(diǎn)間同步,而不是在消費(fèi)者取數(shù)據(jù)時(shí)臨時(shí)拉取纤掸。
- 該模式帶來的副作用也很明顯脐供,除了降低系統(tǒng)性能外,如果鏡像隊(duì)列數(shù)量過多借跪,加之大量的消息進(jìn)入政己,集群內(nèi)部的網(wǎng)絡(luò)帶寬將會(huì)被這種同步通訊大大消耗掉。
- 所以掏愁,在對(duì)可靠性要求較高的場(chǎng)合中適用于該模式歇由。
個(gè)人感覺,在生產(chǎn)環(huán)境中果港,還是使用鏡像模式比較保險(xiǎn)沦泌。
要想使用鏡像模式,不管是通過管理頁面辛掠,還是命令行方式谢谦,只需要簡(jiǎn)單配置即可完成。管理頁面方式就不過多介紹了萝衩,下面說說如何通過命令行來設(shè)置回挽,一條命令就搞定。
添加:
# rabbitmqctl set_policy -p testvhost testha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
Setting policy "testha" for pattern "^" to "{"ha-mode":"all","ha-sync-mode":"automatic"}" with priority "0" for vhost "testvhost" ...
清除:
# rabbitmqctl clear_policy -p testvhost testha
Clearing policy "testha" on vhost "testvhost" ...
查看:
# rabbitmqctl list_policies -p testvhost
Listing policies for vhost "testvhost" ...
vhost name pattern apply-to definition priority
testvhost testha ^ all {"ha-mode":"all","ha-sync-mode":"automatic"} 0
參數(shù)說明:
Virtual host:策略應(yīng)用的 vhost猩谊。
Name:為策略名稱千劈,可以是任何名稱,但建議使用不帶空格的基于 ASCII 的名稱牌捷。
Pattern:與一個(gè)或多個(gè) queue(exchange) 名稱匹配的正則表達(dá)式墙牌,可以使用任何正則表達(dá)式。只有一個(gè)
^
代表匹配所有暗甥,^test
為匹配名稱為 "test" 的 exchanges 或者 queue喜滨。Apply to:Pattern 應(yīng)用對(duì)象。
Priority:配置多個(gè)策略時(shí)的優(yōu)先級(jí)淋袖,值越大鸿市,優(yōu)先級(jí)越高锯梁。沒有指定優(yōu)先級(jí)的消息會(huì)以 0 優(yōu)先級(jí)對(duì)待即碗,對(duì)于超過隊(duì)列所定最大優(yōu)先級(jí)的消息焰情,優(yōu)先級(jí)以最大優(yōu)先級(jí)對(duì)待。
-
Definition:鍵/值對(duì)剥懒,將被插入匹配 queues and exchanges 的可選參數(shù)映射中内舟。
ha-mode
:策略鍵,分為 3 種模式:-
all
:所有的 queue初橘。 -
exctly
:部分(需配置ha-params
參數(shù)验游,此參數(shù)為 int 類型。比如 3保檐,眾多集群中的隨機(jī) 3 臺(tái)機(jī)器)耕蝉。 -
nodes
:指定(需配置ha-params
參數(shù),此參數(shù)為數(shù)組類型夜只。比如 ["rabbit@rabbit2", "rabbit@rabbit3"] 這樣指定為 rabbit2 與 rabbit3 這兩臺(tái)機(jī)器)垒在。
ha-sync-mode
:隊(duì)列同步:-
manual
:手動(dòng)(默認(rèn)模式)。新的隊(duì)列鏡像將不會(huì)收到現(xiàn)有的消息扔亥,它只會(huì)接收新的消息场躯。 -
automatic
:自動(dòng)同步。當(dāng)一個(gè)新鏡像加入時(shí)旅挤,隊(duì)列會(huì)自動(dòng)同步踢关。隊(duì)列同步是一個(gè)阻塞操作。
-
以上就是本篇全部?jī)?nèi)容粘茄,歡迎大家留言交流签舞。