RabbitMQ3.6.3集羣搭建+HAProxy1.6作負載均衡

目錄

[TOC]html

一、基本概念

1.一、RabbitMQ集羣概述

  經過 Erlang 的分佈式特性(經過 magic cookie 認證節點)進行 RabbitMQ 集羣,各 RabbitMQ 服務爲對等節點,即每一個節點都提供服務給客戶端鏈接,進行消息發送與接收。node

  這些節點經過 RabbitMQ HA 隊列(鏡像隊列)進行消息隊列結構複製。本方案中搭建 3 個節點,而且都是磁盤節點(全部節點狀態保持一致,節點徹底對等),只要有任何一個節點可以工做,RabbitMQ 集羣對外就能提供服務。mysql

1.二、軟件負載均衡器HAProxy

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

  HAProxy的特色是:
  一、HAProxy是支持虛擬主機的,,並能支持上萬級別的鏈接;
  二、可以補充Nginx的一些缺點好比Session的保持,cookie的引導等工做;
  三、支持url檢測後端的服務器出問題的檢測會有很好的幫助;
  四、它跟LVS同樣,自己僅僅就只是一款負載均衡軟件;單純從效率上來說HAProxy更會比Nginx有更出色的負載均衡速度,在併發處理上也是優於Nginx的;
  五、HAProxy能夠對mysql讀進行負載均衡,對後端的MySQL節點進行檢測和負載均衡,不過在後端的MySQL slaves數量超過10臺時性能不如LVS,因此我向你們推薦LVS+Keepalived;
  六、可以提供4層,7層代理。HAProxy支持兩種主要的代理模式:"tcp"也即4層(大多用於郵件服務器、內部協議通訊服務器等),和7層(HTTP)。在4層模式 下,HAProxy僅在客戶端和服務器之間轉發雙向流量,7層模式下,HAProxy會分析協議,而且能經過容許、拒絕、交換、增長、修改或者刪除請求 (request)或者回應(response)裏指定內容來控制協議,這種操做要基於特定規則;
  七、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請求。web

二、RabbitMQ的配置步驟

2.一、安裝 Erlang、RabbitMQ

  參考文章Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳實踐正則表達式

2.二、修改 /etc/hosts

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

192.168.0.31 node1
192.168.0.32 node2
192.168.0.33 node3算法

2.二、設置 Erlang Cookie

  RabbitMQ節點之間和命令行工具 (e.g. rabbitmqctl)是使用Cookie互通的,Cookie是一組隨機的數字+字母的字符串。當RabbitMQ服務器啓動的時候,Erlang VM會自動建立一個隨機內容的Cookie文件。若是是經過源安裝RabbitMQ的話,Erlang Cookie 文件在/var/lib/rabbitmq/.erlang.cookie。若是是經過源碼安裝的RabbitMQ,Erlang Cookie文件$HOME/.erlang.cookie。sql

  本文演示的實例是用源碼安裝,因爲這個文件權限是 400,因此須要先修改 node二、node3 中的該文件權限爲 777:ubuntu

lion@node1:~$ chmod 777 .erlang.cookie

  而後將文件複製到node二、node3上面。

node2:

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

node3:

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

  分別在node一、node二、node3將權限恢復過來:

lion@node1:~$ chmod 400 .erlang.cookie

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

lion@node1:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

lion@node2:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

lion@node3:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

2.三、使用detached參數,在後臺啓動Rabbit Node

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

lion@node1:~$ rabbitmqctl stop
Stopping and halting node rabbit@node1 ...
Gracefully halting Erlang VM
lion@node1:~$ rabbitmq-server -detached

  經過rabbitmqctl cluster_status命令,能夠查看和個節點的狀態,節點的名稱是rabbit@shorthostname,

node1:

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

node2:

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

node3:

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

2.四、將node一、node二、node3組成集羣

  由於rabbitmq-server啓動時,會一塊兒啓動節點和應用,它預先設置RabbitMQ應用爲standalone模式。要將一個節點加入到現有的集羣中,你須要中止這個應用並將節點設置爲原始狀態,而後就爲加入集羣準備好了。若是使用./rabbitmqctl stop,應用和節點都將被關閉。因此使用rabbitmqctl stop_app僅僅關閉應用。

node2:

lion@node2:~$ rabbitmqctl stop_app
Stopping node rabbit@node2 ...
lion@node2:~$ rabbitmqctl join_cluster rabbit@node1
Clustering node rabbit@node2 with rabbit@node1 ...
lion@node2:~$ rabbitmqctl start_app
Starting node rabbit@node2 ...

node3:

lion@node3:~$ rabbitmqctl stop_app
Stopping node rabbit@node3 ...
lion@node3:~$ rabbitmqctl join_cluster rabbit@node1
Clustering node rabbit@node3 with rabbit@node1 ...
lion@node3:~$ rabbitmqctl start_app
Starting node rabbit@node3 ...

  此時 node2 與 node3 也會自動創建鏈接。

  若是要使用內存節點,則可使用如下命令:

lion@node2:~$ rabbitmqctl join_cluster --ram rabbit@node1

  集羣配置好後,能夠在 RabbitMQ 任意節點上執行 rabbitmqctl cluster_status 來查看是否集羣配置成功。

node1:

lion@node1:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node1 ...
[{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]},
 {running_nodes,[rabbit@node1]},
 {cluster_name,<<"rabbit@node1">>},
 {partitions,[]},
 {alarms,[{rabbit@node1,[]}]}]

node2:

lion@node2:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node2 ...
[{nodes,[{disc,[rabbit@node1,rabbit@node2]}]},{alarms,[{rabbit@node1,[]}]}]

node3:

lion@node3:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node3 ...
[{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]},
 {alarms,[{rabbit@node1,[]}]}]

  同時在Web管理工具中也能夠看到效果

 

2.五、RabbitMQ鏡像功能

  使用Rabbit鏡像功能,須要基於RabbitMQ策略來實現,策略是用來控制和修改羣集範圍的某個vhost隊列行爲和Exchange行爲

lion@node2:~$ rabbitmqctl set_policy -p hrsystem ha-allqueue"^" '{"ha-mode":"all"}'

這行命令在vhost名稱爲hrsystem建立了一個策略,策略名稱爲ha-allqueue,策略模式爲 all 即複製到全部節點,包含新增節點,策略正則表達式爲 「^」 表示全部匹配全部隊列名稱。

  例以下面的命令,^message 這個規則要根據本身修改,這個是指同步"message"開頭的隊列名稱,咱們配置時使用的應用於全部隊列,因此表達式爲"^"。

lion@node2:~$ rabbitmqctl set_policy -p hrsystem ha-allqueue "^message" '{"ha-mode":"all"}'

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

2.六、安裝軟件負載均衡器HAProxy1.6

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

lion@node4:~$ sudo apt-cache showpkg haproxy

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

  在寫本文的時候,官方包是沒有1.6版本的,咱們能夠經過如下命令來安裝 :

lion@node4:~$ sudo add-apt-repository ppa:vbernat/haproxy-1.6
lion@node4:~$ sudo apt-get update
lion@node4:~$ sudo apt-get install haproxy

  安裝完之後,能夠經過如下命令,查看安裝的版本

lion@node4:~$ haproxy -v
HA-Proxy version 1.6.7 2016/07/13
Copyright 2000-2016 Willy Tarreau <willy@haproxy.org>

  安裝完之後,配置文件的目錄在/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

lion@node4:~$ sudo service haproxy restart
 * Restarting haproxy haproxy                                                                                                 [ OK ]

  而後用瀏覽器輸入http://:1080/haproxy?stats,能夠看到如下結果,說明node一、node二、node3都已經搭建好了:

  

2.七、測試結果 ,向HAProxy發送消息

  使用Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳實踐中的代碼來發送消息, 在node3上咱們將消息發送到node4(192.168.0.34)上

原來默認的guest用戶是禁止遠程訪問的,若是要使用lion賬號訪問,須要在web管理控制檯中開啓lion對Virtual Host訪問

Console1(node3):

lion@node3:~/_code/_rabbitmq/_golang$ go run producer_hello.go
2016/07/29 12:46:50 dialing "amqp://lion:123456@192.168.0.34: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):

lion@node1:~/_code/_rabbitmq/_golang$ go run consumer_hello.go
2016/07/25 17:37:12 dialing "amqp://guest:guest@localhost: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上能夠正常接收。

三、參考閱讀

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負載均衡軟件的優缺點詳解

相關文章
相關標籤/搜索