最近做到的項目中,有着龐大的日數據處理量(大概1天200W條),都需要通過MQ來傳遞數據,並進行解析持久化。所以接觸了下Rabbitmq的鏡像集羣搭建,記錄下方便以後再次用到。
先講下整體的架構,計劃打算使用3臺MQ服務器,然後用2臺haproxy服務器進行負載均衡處理,再使用keepalived來處理兩臺負載均衡處理器的單點問題,以期實現高可用高負載的MQ集羣。本片只涉及前兩部分。
涉及服務器均爲
CentOS7 64位
所使用到的Rabbitmq版本
rabbitmq-server-generic-unix-3.6.15.tar.xz
1.Rabbitmq單機環境搭建
在進行Rabbitmq集羣搭建之前,首先需要在3臺MQ服務器上部署單機Rabbitmq。
1.安裝Erlang
因爲Rabbitmq是依賴Erlang的,所以需要先安裝Erlang。
(1)安裝編譯環境,如果已經安裝過就不需要再安一次了。
yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel
(2)安裝ncurses
yum -y install ncurses-devel
(3)安裝unixODBC
yum install unixODBC unixODBC-devel
(4)下載安裝erlang
//進入想要安裝的目錄,假設我這裏是想把erlang安裝在/home目錄下
cd /home
wget http://erlang.org/download/otp_src_20.3.tar.gz
解壓
tar -zxvf otp_src_20.3.tar.gz
初始化
//進入解壓完的文件夾
cd otp_src_20.3
//指定不用java編譯,填不填無所謂,就是不寫會報個警告,無影響
./configure --prefix /home/erlang --without-javac
安裝
make
make install
安裝完畢後配置下環境變量
vim /etc/profile
添加
export PATH=$PATH:/home/erlang/bin/
保存退出,並執行
source /etc/profile
試下能否使用erlang
erl
出現如下就表示安裝成功了,然後可以輸入halt().
退出
2.在xx.xx.2.1
,xx.xx.2.2
,xx.xx.2.3
3臺MQ服務器上安裝Rabbitmq。
(1)下載rabbitmq-server-generic-unix-3.6.15.tar.xz
cd /home
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.15/rabbitmq-server-generic-unix-3.6.15.tar.xz
解壓
tar -xvf rabbitmq-server-generic-unix-3.6.15.tar.xz
該方式下載解壓後可以直接使用,無需再編譯安裝
設置環境變量
vim /etc/profile
添加
export PATH=/home/rabbitmq_server-3.6.15/sbin/:$PATH
保存退出並執行
source /etc/profile
進入安裝目錄
cd /home/rabbitmq_server-3.6.15/sbin/
開啓後臺管理工具
./rabbitmq-plugins enable rabbitmq_management
啓動Rabbitmq
./rabbitmq-server -detached #後臺運行rabbitmq
#注,我在用該方式啓動Rabbitmq時會報錯,所以我用的是這個方法啓動
./rabbitmq-server start &
可以查看下進程或者stats看下是否啓動
ps -ef|grep rabbitmq
或者
rabbitmqctl status
可以看到上面我塗掉的status of node xxxx
這個xxxx就是該rabbitmq節點的名稱,之後在集羣設置中會用到,這裏可以記錄下xx.xx.2.1
的節點名。
這樣RabbitMq就算是啓動了,但是還需要設置新的用戶和開放端口供外部訪問。
開放端口
iptables -I INPUT -p tcp --dport 15672 -j ACCEPT
添加用戶
rabbitmqctl add_user admin 123456 #用戶名 密碼
添加權限
./rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
修改用戶角色
./rabbitmqctl set_user_tags admin administrator
然後就可以通過15672端口訪問網頁控制檯了
訪問的地址爲 http://xx.xx.2.1:15672 前半段爲MQ服務器ip地址,或者外網映射地址。
使用剛纔的用戶密碼就可以登入了。
然後在xx.xx.2.2和xx.xx.2.3上重複一遍安裝Rabbitmq。
2.Rabbitmq鏡像集羣搭建
通過上一步,已經成功在3臺MQ服務器上安裝了單機的Rabbitmq,並保證有同一用戶名密碼的用戶。
現在,使用xx.xx.2.1
作爲’主節點’
1.xx.xx.2.1
的.erlang.cookie
文件的拷貝複製
首先找到該文件
find -name .erlang.cookie
上面塗掉的是我複製出來的同一個文件,找到該文件後複製一份,然後替換掉xx.xx.2.2
和xx.xx.2.3
上的同文件,使得3臺MQ服務器上的該文件都爲xx.xx.2.1
的。
即三臺服務器必須具有相同的cookie,如果不相同的話,無法搭建集羣(注:該文件爲隱藏文件,複製拷貝的時候還要注意各臺服務器上該文件的權限,一定要保證替換完後的權限和替換前一致)
2.在xx.xx.2.2
和xx.xx.2.3
服務器上執行如下操作加入到MQ集羣
abbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@h-ncdrdcs7
#rabbit@h-ncdrdcs7是rabbitmq node name,上面在查看rabbitmq運行情況時我
#有提到,這裏都使用xx.xx.2.1上的rabbitmq node name就行
rabbitmqctl start_app
#其中--ram代表是內存節點,如果希望是磁盤節點則不用加--ram,
#在rabbitmq集羣中,至少需要一個磁盤節點
查看集羣狀態
rabbitmqctl cluster_status
當然也可以通過15672從頁面上查看
這裏我使用http://xx.xx.2.1:15672
來查看,如下狀態就表示集羣已經搭建好了
設置成鏡像隊列
rabbitmqctl set_policy ha-all "^test\." '{"ha-mode":"all"}'
#意思表示以test.開頭的queue都會複製到各個節點 ["^"匹配所有],這個大家自行修改
至此,Rabbitmq鏡像集羣搭建完畢。
PS:
這裏我遇到一個大坑,稍微提一下,就是2,3兩臺MQ服務器在加入1時,出現無法解析服務器名的問題,然後這裏需要在3臺服務器的/etc/hosts文件中添加機器名-ip,然後需要將3臺MQ都重啓一下才能夠加入(是整個重啓,單純重啓app沒用的)。
3.Haproxy負載均衡
在xx.xx.1.1
上安裝Haproxy
yum install haproxy
安裝過程中會提示是否安裝,輸入y
,回車
即可
安裝完畢後需要修改配置
vim /etc/haproxy/haproxy.cfg
在末尾添加內容如下
#---------------------------------------------------------------------
# my
#---------------------------------------------------------------------
listen rabbitmq
bind 0.0.0.0:5672
mode tcp
option tcplog
balance roundrobin
#option tcpka
server rabbit1 xx.xx.1.1:5672 check inter 5s rise 2 fall 3
server rabbit2 xx.xx.1.2:5672 check inter 5s rise 2 fall 3
server rabbit3 xx.xx.1.3:5672 check inter 5s rise 2 fall 3
然後運行Haproxy
haproxy -f /etc/haproxy/haproxy.cfg
重啓的方式是
service haproxy restart
PS:
如果在運行時出現need mode http什麼的錯誤的話,可以嘗試註釋掉default中的mode http,按理來說在監聽節點中不存在設置時會自動使用默認設置,如果存在則會負載默認設置,但不知道爲什麼,我在啓動時出現了默認設置覆蓋實際設置的問題,不過只要注掉默認設置即可,問題不大。
然後可以嘗試用生產者端或者消費者端向xx.xx.1.1
負載服務器上發/收消息,然後15672查看queue狀態即可,或者在haproxy配置文件中加入15672端口的監聽,直接訪問
http://xx.xx.1.1:15672
,如果可以訪問並能通過設置的用戶名密碼登入,則表示負載均衡配置成功。
另一臺負載均衡服務器也可以做相同的配置,然後使用keepalived來檢測兩臺負載服務器的單點問題即可。以後有時間我會把這部分補充完整。當然現階段使用單負載服務器直接訪問集羣也是可以的。