1. 程式人生 > > RabbitMQ3.6.3叢集搭建+HAProxy1.6做負載均衡

 RabbitMQ3.6.3叢集搭建+HAProxy1.6做負載均衡

 

目錄

目錄

1、基本概念

1.1、RabbitMQ叢集概述

  通過 Erlang 的分散式特性(通過 magic cookie 認證節點)進行 RabbitMQ 叢集,各 RabbitMQ 服務為對等節點,即每個節點都提供服務給客戶端連線,進行訊息傳送與接收。

  這些節點通過 RabbitMQ HA 佇列(映象佇列)進行訊息佇列結構複製。本方案中搭建 3 個節點,並且都是磁碟節點(所有節點狀態保持一致,節點完全對等),只要有任何一個節點能夠工作,RabbitMQ 叢集對外就能提供服務。

1.2、軟體負載均衡器HAProxy

  HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支援虛擬主機,它是免費、快速並且可靠的一種解決方案。根據官方資料,其最高極限支援10G的併發。HAProxy支援從4層至7層的網路交換,即覆蓋所有的TCP協議。就是說,Haproxy 甚至還支援 Mysql 的均衡負載。

  HAProxy的特點是:
  1、HAProxy是支援虛擬主機的,,並能支援上萬級別的連線;
  2、能夠補充Nginx的一些缺點比如Session的保持,cookie的引導等工作;
  3、支援url檢測後端的伺服器出問題的檢測會有很好的幫助;
  4、它跟LVS一樣,本身僅僅就只是一款負載均衡軟體;單純從效率上來講HAProxy更會比Nginx有更出色的負載均衡速度,在併發處理上也是優於Nginx的;
  5、HAProxy可以對mysql讀進行負載均衡,對後端的MySQL節點進行檢測和負載均衡,不過在後端的MySQL slaves數量超過10臺時效能不如LVS,所以我向大家推薦LVS+Keepalived;
  6、能夠提供4層,7層代理。HAProxy支援兩種主要的代理模式:"tcp"

也即4層(大多用於郵件伺服器、內部協議通訊伺服器等),和7層(HTTP)。在4層模式 下,HAProxy僅在客戶端和伺服器之間轉發雙向流量,7層模式下,HAProxy會分析協議,並且能通過允許、拒絕、交換、增加、修改或者刪除請求 (request)或者回應(response)裡指定內容來控制協議,這種操作要基於特定規則;
  7、HAProxy的演算法現在也越來越多了,具體有如下8種:
     ①roundrobin,表示簡單的輪詢,這個不多說,這個是負載均衡基本都具備的;
     ②static-rr,表示根據權重,建議關注;
     ③leastconn,表示最少連線者先處理,建議關注;
     ④source,表示根據請求源IP,這個跟Nginx的IP_hash機制類似,我們用其作為解決session問題的一種方法,建議關注;
     ⑤ri,表示根據請求的URI;
     ⑥rl_param,表示根據請求的URl引數'balance url_param' requires an URL parameter name;
     ⑦hdr(name),表示根據HTTP請求頭來鎖定每一次HTTP請求;
     ⑧rdp-cookie(name),表示根據據cookie(name)來鎖定並雜湊每一次TCP請求。

2、RabbitMQ的配置步驟

2.1、安裝 Erlang、RabbitMQ

  參考文章Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳實踐

2.2、修改 /etc/hosts

  加入叢集 3 個節點的對應關係:

192.168.0.31 node1
192.168.0.32 node2
192.168.0.33 node3

  RabbitMQ節點之間和命令列工具 (e.g. rabbitmqctl)是使用Cookie互通的,Cookie是一組隨機的數字+字母的字串。當RabbitMQ伺服器啟動的時候,Erlang VM會自動建立一個隨機內容的Cookie檔案。如果是通過源安裝RabbitMQ的話,Erlang Cookie 檔案在/var/lib/rabbitmq/.erlang.cookie。如果是通過原始碼安裝的RabbitMQ,Erlang Cookie檔案$HOME/.erlang.cookie。

  本文演示的例項是用原始碼安裝,由於這個檔案許可權是 400,所以需要先修改 node2、node3 中的該檔案許可權為 777:

[email protected]:~$ chmod 777 .erlang.cookie

  然後將檔案複製到node2、node3上面。

node2:

[email protected]:~$ chmod 777 .erlang.cookie
[email protected]:~$ scp -r node1:/home/lion/.erlang.cookie ~/
[email protected]'s password:
.erlang.cookie                                                                                     100%   20     0.0KB/s   00:00

node3:

[email protected]:~$ chmod 777 .erlang.cookie
[email protected]:~$ scp -r node1:/home/lion/.erlang.cookie ~/
[email protected]'s password:
.erlang.cookie                                                                                     100%   20     0.0KB/s   00:00

  分別在node1、node2、node3將許可權恢復過來:

[email protected]:~$ chmod 400 .erlang.cookie

  最後分別在確認三臺機器上的.erlang.cookie的值是一致的

[email protected]:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

[email protected]:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

[email protected]:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

2.3、使用detached引數,在後臺啟動Rabbit Node

  要先停止現有的Rabbitmq-server,再重新在後臺支行

[email protected]:~$ rabbitmqctl stop
Stopping and halting node [email protected] ...
Gracefully halting Erlang VM
[email protected]:~$ rabbitmq-server -detached

  通過rabbitmqctl cluster_status命令,可以檢視和個節點的狀態,節點的名稱是[email protected]

node1:

[email protected]:~$ rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected]]}]},
 {running_nodes,[[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]}]}]

node2:

[email protected]:~$ rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected]]}]},
 {running_nodes,[[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]}]}]

node3:

[email protected]:~$ rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected]]}]},
 {running_nodes,[[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]}]}]

2.4、將node1、node2、node3組成叢集

  因為rabbitmq-server啟動時,會一起啟動節點和應用,它預先設定RabbitMQ應用為standalone模式。要將一個節點加入到現有的叢集中,你需要停止這個應用並將節點設定為原始狀態,然後就為加入叢集準備好了。如果使用./rabbitmqctl stop,應用和節點都將被關閉。所以使用rabbitmqctl stop_app僅僅關閉應用。

node2:

[email protected]:~$ rabbitmqctl stop_app
Stopping node [email protected] ...
[email protected]:~$ rabbitmqctl join_cluster [email protected]
Clustering node [email protected] with [email protected] ...
[email protected]:~$ rabbitmqctl start_app
Starting node [email protected] ...

node3:

[email protected]:~$ rabbitmqctl stop_app
Stopping node [email protected] ...
[email protected]:~$ rabbitmqctl join_cluster [email protected]
Clustering node [email protected] with [email protected] ...
[email protected]:~$ rabbitmqctl start_app
Starting node [email protected] ...

  此時 node2 與 node3 也會自動建立連線。

  如果要使用記憶體節點,則可以使用以下命令:

[email protected]:~$ rabbitmqctl join_cluster --ram [email protected]

  叢集配置好後,可以在 RabbitMQ 任意節點上執行 rabbitmqctl cluster_status 來檢視是否叢集配置成功。

node1:

[email protected]:~$ rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected],[email protected]]}]},
 {running_nodes,[[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]}]}]

node2:

[email protected]:~$ rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected]]}]},{alarms,[{[email protected],[]}]}]

node3:

[email protected]:~$ rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected],[email protected]]}]},
 {alarms,[{[email protected],[]}]}]

  同時在Web管理工具中也可以看到效果

2.5、RabbitMQ映象功能

  使用Rabbit映象功能,需要基於RabbitMQ策略來實現,策略是用來控制和修改群集範圍的某個vhost佇列行為和Exchange行為

[email protected]:~$ rabbitmqctl set_policy -p hrsystem ha-allqueue"^" '{"ha-mode":"all"}'

這行命令在vhost名稱為hrsystem建立了一個策略,策略名稱為ha-allqueue,策略模式為 all 即複製到所有節點,包含新增節點,策略正則表示式為 “^” 表示所有匹配所有佇列名稱。

  例如下面的命令,^message 這個規則要根據自己修改,這個是指同步"message"開頭的佇列名稱,我們配置時使用的應用於所有佇列,所以表示式為"^"。

[email protected]:~$ rabbitmqctl set_policy -p hrsystem ha-allqueue "^message" '{"ha-mode":"all"}'

  更多set_policy說明:http://www.rabbitmq.com/man/rabbitmqctl.1.man.html

2.6、安裝軟體負載均衡器HAProxy1.6

  由於Ubuntu的快速發展,官方的源可能不是最新的版本,大多數時候安裝可能是1.4.24,可以通過以下命令,查詢官方提供的版本號:

[email protected]:~$ sudo apt-cache showpkg haproxy

node4是一臺新的機器 ,IP地址是192.168.0.34

  在寫本文的時候,官方包是沒有1.6版本的,我們可以通過以下命令來安裝 :

[email protected]:~$ sudo add-apt-repository ppa:vbernat/haproxy-1.6
[email protected]:~$ sudo apt-get update
[email protected]:~$ sudo apt-get install haproxy

  安裝完以後,可以通過以下命令,檢視安裝的版本

[email protected]:~$ haproxy -v
HA-Proxy version 1.6.7 2016/07/13
Copyright 2000-2016 Willy Tarreau <[email protected]>

  安裝完以後,配置檔案的目錄在/etc/haproxy/haproxy.cfg,以下是我修改後的配置檔案

###########全域性配置#########
global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy     # 改變當前工作目錄
    stats socket /run/haproxy/admin.sock mode 660 level admin   # 建立監控所用的套接字目錄
    pidfile  /var/run/haproxy.pid   # haproxy的pid存放路徑,啟動程序的使用者必須有許可權訪問此檔案 
    maxconn  4000                   # 最大連線數,預設4000 user haproxy # 預設使用者 group haproxy # 預設使用者組 daemon # 建立1個程序進入deamon模式執行。此引數要求將執行模式設定為"daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # Default ciphers to use on SSL-enabled listening sockets. # For more information, see ciphers(1SSL). This list is from: # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS ssl-default-bind-options no-sslv3 ###########預設配置######### defaults log global mode http # 預設的模式mode { tcp|http|health },tcp是4層,http是7層,health只會返回OK option httplog # 採用http日誌格式 option dontlognull # 啟用該項,日誌中將不會記錄空連線。所謂空連線就是在上游的負載均衡器 # 或者監控系統為了探測該 服務是否存活可用時,需要定期的連線或者獲取某 # 一固定的元件或頁面,或者探測掃描埠是否在監聽或開放等動作被稱為空連線; # 官方文件中標註,如果該服務上游沒有其他的負載均衡器的話,建議不要使用 # 該引數,因為網際網路上的惡意掃描或其他動作就不會被記錄下來 timeout connect 5000 # 連線超時時間 timeout client 50000 # 客戶端連線超時時間 timeout server 50000 # 伺服器端連線超時時間 option httpclose # 每次請求完畢後主動關閉http通道 option httplog # 日誌類別http日誌格式 #option forwardfor # 如果後端伺服器需要獲得客戶端真實ip需要配置的引數,可以從Http Header中獲得客戶端ip option redispatch # serverId對應的伺服器掛掉後,強制定向到其他健康的伺服器 timeout connect 10000 # default 10 second timeout if a backend is not found maxconn 60000 # 最大連線數 retries 3 # 3次連線失敗就認為服務不可用,也可以通過後面設定 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http #################################################################### listen http_front bind 0.0.0.0:1080 #監聽埠 stats refresh 30s #統計頁面自動重新整理時間 stats uri /haproxy?stats #統計頁面url stats realm Haproxy Manager #統計頁面密碼框上提示文字 stats auth admin:admin #統計頁面使用者名稱和密碼設定 #stats hide-version #隱藏統計頁面上HAProxy的版本資訊 #####################我把RabbitMQ的管理介面也放在HAProxy後面了############################### listen rabbitmq_admin bind 0.0.0.0:8004 server node1 192.168.0.31:15672 server node2 192.168.0.32:15672 server node3 192.168.0.33:15672 #################################################################### listen rabbitmq_cluster bind 0.0.0.0:5672 option tcplog mode tcp timeout client 3h timeout server 3h option clitcpka balance roundrobin #負載均衡演算法(#banlance roundrobin 輪詢,balance source 儲存session值,支援static-rr,leastconn,first,uri等引數) #balance url_param userid #balance url_param session_id check_post 64 #balance hdr(User-Agent) #balance hdr(host) #balance hdr(Host) use_domain_only #balance rdp-cookie #balance leastconn #balance source //ip server node1 192.168.0.31:5672 check inter 5s rise 2 fall 3 #check inter 2000 是檢測心跳頻率,rise 2是2次正確認為伺服器可用,fall 3是3次失敗認為伺服器不可用 server node2 192.168.0.32:5672 check inter 5s rise 2 fall 3 server node3 192.168.0.33:5672 check inter 5s rise 2 fall 3

  更多Haproxy的配置檔案介紹參考:http://www.haproxy.org/download/1.4/doc/configuration.txt

  重新啟動HAProxy

[email protected]:~$ sudo service haproxy restart
 * Restarting haproxy haproxy                                                                                                 [ OK ]

  然後用瀏覽器輸入http://:1080/haproxy?stats,可以看到以下結果,說明node1、node2、node3都已經搭建好了:

  

2.7、測試結果 ,向HAProxy傳送訊息

  使用Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳實踐中的程式碼來發送訊息, 在node3上我們將訊息傳送到node4(192.168.0.34)上

原來預設的guest使用者是禁止遠端訪問的,如果要使用lion帳號訪問,需要在web管理控制檯中開啟lion對Virtual Host訪問

Console1(node3):

[email protected]:~/_code/_rabbitmq/_golang$ go run producer_hello.go
2016/07/29 12:46:50 dialing "amqp://lion:[email protected]:5672/"
2016/07/29 12:46:50 got Connection, getting Channel
2016/07/29 12:46:50 got queue, declaring "test-idoall-queues"
2016/07/29 12:46:50 declared queue, publishing 16B body ("hello idoall.org")
2016/07/29 12:46:50 published 16B OK

Console(node1):

[email protected]:~/_code/_rabbitmq/_golang$ go run consumer_hello.go
2016/07/25 17:37:12 dialing "amqp://guest:[email protected]:5672/"
2016/07/25 17:37:12 got Connection, getting Channel
2016/07/25 17:37:12 got queue, declaring "test-idoall-queues"
2016/07/25 17:37:12 Queue bound to Exchange, starting Consume
2016/07/25 17:37:12  [*] Waiting for messages. To exit press CTRL+C
2016/07/25 17:37:12 Received a message: hello idoall.org

  在上面的程式碼中,我們可以看到在node3是向192.168.0.34這臺HAProxy上傳送訊息,然後在node1上可以正常接收。

3、參考閱讀

Haproxy 配置項\配置例項

How to Install HAProxy Load Balancer on Ubuntu

http://www.rabbitmq.com/clustering.html

Can't access RabbitMQ web management interface after fresh install

Nginx/LVS/HAProxy負載均衡軟體的優缺點詳解


博文作者:迦壹
部落格地址:RabbitMQ3.6.3叢集搭建+HAProxy1.6做負載均衡
轉載宣告:可以轉載, 但必須以超連結形式標明文章原始出處和作者資訊及版權宣告,謝謝合作!