RabbitMq 基於 keepalived+haproxy實現高可用

1  概述node

rabbitmq做爲消息隊列,普遍用於生產環境,可是,若是單節點,將致使故障後,生產環境不可用,所以,須要部署高可用環境linux

本文將介紹基於keepalived+haproxy實現rabbitmq的高可用c++

rabbitmq的集羣中,全部節點均可讀寫,所以,可用haproxy調度到後端的任意一臺rabbitmq上。web

環境準備正則表達式

三個節點mq-01 mq-02 mq-03 ,這裏服務器複用了redis的服務器節點,因此機器名忽略。redis

添加hosts文件vim

#這一步很關鍵,全部的節點都要配置同樣,不然mq啓動會超時,集羣功能也不會成功後端

vim /etc/hosts
192.168.70.32 mq-01
192.168.70.33 mq-02
192.168.70.34 mq-03

另外兩臺主機用於安裝keepalived+haproxybash

ip:服務器

192.168.70.35

192.168.70.36

vip:192.168.70.37

2  編譯安裝erlang

服務包:otp_src_20.2.tar.gz

編譯步驟以下

yum -y install make cmake gcc gcc-c++ bison bison-devel ncurses ncurses-devel openssl-devel
tar xf otp_src_20.2.tar.gz  -C /app
cd /app/otp_src_20.2/
./configure --prefix=/app/erlang && make && make install

#測試erlang是否安裝成功

cd /app/erlang/bin/
./erl

3  編譯安裝rabbitmq

服務包:rabbitmq-server-generic-unix-3.7.4.tar.xz 

tar xf rabbitmq-server-generic-unix-3.7.4.tar.xz -C /app
mv /app/rabbitmq_server-3.7.4/ /app/rabbitmq
vim /etc/profile
export PATH=$PATH:/app/erlang/bin:/app/rabbitmq/sbin
source /etc/profile

前臺啓動,測試啓動服務是否報錯

./rabbitmq/sbin/rabbitmq-server #前臺模式(默認)

後臺啓動,建議運行服務的方式

/app/rabbitmq/sbin/rabbitmq-server -detached #之後臺模式啓動(建議),尤爲是使用web圖形界面時

/app/rabbitmq/sbin/rabbitmq-plugins enable rabbitmq_management #建議安裝web圖形化管理工具,如不須要 能夠不裝,15672爲rabbitmq服務的圖形管理端口

#建立桌面端登錄帳號

rabbitmqctl add_vhost vh
rabbitmqctl add_user root hns..2018
rabbitmqctl set_user_tags root management
rabbitmqctl set_permissions -p vh root ".*" ".*" ".*"

#訪問

http://192.168.70.32:15672/

#若是啓動不起來 多是系統自帶的erl版本問題 刪除/usr/bin/erl 而後source PATH文件便可

4  配置高可用

4.1配置mq高可用

把節點redis-01的.erlang.cookie權限設置爲777,而且拷貝到其餘兩個節點,同時,權限也都要設置爲777.erlang.cookie的路徑可能不同,用find命令查找出來

redis-01執行以下命令

chmod 777 /root/.erlang.cookie

刪掉02和03的.erlang.cookie

/root/.erlang.cookie

在01上執行

scp /root/.erlang.cookie 192.168.70.33:/root

scp /root/.erlang.cookie 192.168.70.34:/root

拷貝完成後,01,02和03執行以下,恢復原來的權限

chmod 400 /root/.erlang.cookie

確認三臺機器的.erlang.cookie值同樣

cat /root/.erlang.cookie

啓動三個mq節點

rabbitmq-server -detached

中止02和03兩個節點app

 rabbitmqctl stop_app

在02 和 03上分別執行以下命令

rabbitmqctl join_cluster rabbit@redis-01

rabbitmqctl start_app

此時,若是沒有報錯,三個節點的mq已經組成rabbit集羣

用以下命令進行查看集羣狀態

rabbitmqctl cluster_status

隨便中止某一臺rabbitmq,數據均可以從其餘兩臺讀取

到這裏,rabbitmq集羣已經完成,還需配置haproxy+keepalived來實現高可用,只用一個vip來進行調度

4.2 鏡像隊列的設置

鏡像隊列的配置經過添加policy完成,policy添加的命令爲: 
rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority] 
-p Vhost: 可選參數,針對指定vhost下的queue進行設置 
Name: policy的名稱 
Pattern: queue的匹配模式(正則表達式) 
Definition: 鏡像定義,包括三個部分 ha-mode,ha-params,ha-sync-mode 
    ha-mode: 指明鏡像隊列的模式,有效值爲 all/exactly/nodes 
        all表示在集羣全部的節點上進行鏡像 
        exactly表示在指定個數的節點上進行鏡像,節點的個數由ha-params指定 
        nodes表示在指定的節點上進行鏡像,節點名稱經過ha-params指定 
    ha-params: ha-mode模式須要用到的參數 
    ha-sync-mode: 鏡像隊列中消息的同步方式,有效值爲automatic,manually 
Priority: 可選參數, policy的優先級

例子:

策略名稱 ha-allqueue,對隊列名稱以app開頭的全部隊列進行鏡像,策略模式爲 all 即複製到全部節點,包含新增節點,策略正則表達式爲 「^」 表示全部匹配全部隊列名稱。

policy的設置命令爲:

rabbitmqctl set_policy -p vh ha-allqueue "^" '{"ha-mode":"all"}'

策略名稱ha-2number,對隊列名稱以app開頭的全部隊列進行鏡像,並在集羣的兩個節點上完成鏡像,

policy的設置命令爲: 

rabbitmqctl set_policy -p vh ha-2number "^app" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'

策略名稱ha-2node,對隊列名稱以app開頭的全部隊列進行鏡像,並在集羣的rabbit@redis-01和rabbit@redis-02兩個指定的節點上完成鏡像,

policy的設置命令爲: 

rabbitmqctl set_policy -p vh ha-2node "^web" '{"ha-mode":"nodes","ha-params":["rabbit@redis-01","rabbit@redis-02"]}'

生產環境能夠根據實際狀況來配置,第一個狀況,雖然匹配了全部,可是當某一個隊列不消費,撐爆集羣的時候,全部的隊列都會被影響,第三個狀況指定了全部的 2個隊列,只有這兩個隊列纔會擁有web開通的隊列鏡像信息。
4.3 集羣管理相關命令

查看集羣狀態

rabbitmq-server cluster-status

加入集羣

rabbitmqctl join_cluster rabbit@redis-01

查看策略

rabbitmqctl list_policies -p vh

清除策略

rabbitmqctl  clear_policy -p vh ha-allweb3.0

5  haproxy+keepalived編譯安裝

5.1 haproxy編譯安裝

軟件包:haproxy-1.7.9.tar.gz

tar -xf  haproxy-1.7.9.tar.gz -C  /usr/local
groupadd  -r  -g  159  haproxy
useradd -g haproxy -r -s /sbin/nologin -u 159 haproxy
cd /usr/local/haproxy-1.7.9/
make TARGET=linux26  ARCH=X86_64 PREFIX=/app/haproxy
make install PREFIX=/app/haproxy
mkdir /etc/haproxy/
vim /etc/haproxy/haproxy.cfg #放在附錄文件
vim /etc/init.d/haproxy  #放着附錄文件
chmod 777 /etc/init.d/haproxy
service haproxy start
chkconfig --add haproxy 
chkconfig --level 2345  haproxy on

5.2 keepalived編譯安裝

keepalived編譯安裝見博客:<Redis 高可用 基於Sentinel + keepalived 實現>,連接以下,可是keepalived的配置文件有區別,見附錄。其餘步驟都同樣

http://www.javashuo.com/article/p-dcwaitmh-gy.html

5.3 測試

haproxy和keepalived啓動後,斷開主keepalived,vip會排異到另外一臺服務器上

另外,經過訪問vip 192.168.70.37 的監聽5672端口,能夠把請求調度到後端的三臺mq上,且任何一臺mq異常,請求將不會調度到這臺異常的mq上,即服務正常。

測試成功

6 附錄

6.1 haproxy配置文件

兩臺配置都同樣

vim /etc/haproxy/haproxy.cfg 
global
    log 127.0.0.1 local0 info
    maxconn 8192
        user haproxy
    group haproxy
defaults
    timeout connect     3500
    timeout queue       11000
    timeout tarpit      12000
    timeout client      30000
    timeout http-request    40000
    timeout http-keep-alive 5000
    timeout server      40000
    timeout check       7000
    option  contstats
    option  log-health-checks
#################################
##監控查看本地狀態#####
listen admin_stats
        bind 0.0.0.0:9188
    mode http
    log 127.0.0.1 local0 err
    stats refresh 30s
    stats uri /haproxy
    stats realm welcome login\ Haproxy
    stats auth adminuser:password123456789
    stats hide-version
    stats admin if TRUE
####################################
###反代監控
frontend server
    bind *:5672
    log global
    mode tcp
    #option forwardfor
    default_backend rabbitmq
    maxconn 3
backend rabbitmq
    mode tcp
    log global
    balance roundrobin
    server   mq-01 192.168.70.32:5672  check inter 5s rise 2 fall 3   #check inter 2000 是檢測心跳頻率,rise 2是2次正確認爲服務器可用,fall 3是3次失敗認爲服務器不可用
    server   mq-02 192.168.70.33:5672  check inter 5s rise 2 fall 3
    server   mq-03 192.168.70.34:5672  check inter 5s rise 2 fall 3

#以上爲完整的haproxy配置,若是在rabbitmq的消息消費端出現錯誤: o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: connection error,可是請求能夠被正常消費,
解決辦法是:修改 HAProxy 中的timeout client超時時間,配置大於系統的tcp_keepalive_time間隔時間(推薦)即設置timeout client和 timeout server值
參考文章;配置以下:
frontend mqctl
    bind *:15672
    log global
    mode tcp
    #option forwardfor
    default_backend mqweb
    maxconn 3
    timeout client  3h

backend mqweb
    mode tcp
    log global
    balance roundrobin
    timeout server  3h
    server   prd-can3-0-mq01 192.168.70.71:15672  check inter 5s rise 2 fall 3   #check inter 2000 是檢測心跳頻率,rise 2是2次正確認爲服務器可用,fall 3是3次失敗認爲服務器不可用
    server   prd-can3-0-mq02 192.168.70.81:15672  check inter 5s rise 2 fall 3

6.2 haproxy啓動文件

#編譯安裝的執行文件的路徑須要調整,其餘地方可保持一致
vim /etc/init.d/haproxy
#!/bin/sh
#
# haproxy
#
# chkconfig:   - 85 15
# description:  HAProxy is a free, very fast and reliable solution \
#               offering high availability, load balancing, and \
#               proxying for TCP and  HTTP-based applications
# processname: haproxy
# config:      /etc/haproxy/haproxy.cfg
# pidfile:     /var/run/haproxy.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
exec="/app/haproxy/sbin/haproxy"  #這裏要注意,編譯安裝的執行文件的路徑
prog=$(basename $exec)
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
cfgfile=/etc/haproxy/haproxy.cfg
pidfile=/var/run/haproxy.pid
lockfile=/var/lock/subsys/haproxy
check() {
    $exec -c -V -f $cfgfile $OPTIONS
}
start() {
    $exec -c -q -f $cfgfile $OPTIONS
    if [ $? -ne 0 ]; then
        echo "Errors in configuration file, check with $prog check."
        return 1
    fi
    echo -n $"Starting $prog: "
    # start it up here, usually something like "daemon $exec"
    daemon $exec -D -f $cfgfile -p $pidfile $OPTIONS
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
stop() {
    echo -n $"Stopping $prog: "
    # stop it here, often "killproc $prog"
    killproc $prog 
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
restart() {
    $exec -c -q -f $cfgfile $OPTIONS
    if [ $? -ne 0 ]; then
        echo "Errors in configuration file, check with $prog check."
        return 1
    fi
    stop
    start
}
reload() {
    $exec -c -q -f $cfgfile $OPTIONS
    if [ $? -ne 0 ]; then
        echo "Errors in configuration file, check with $prog check."
        return 1
    fi
    echo -n $"Reloading $prog: "
    $exec -D -f $cfgfile -p $pidfile $OPTIONS -sf $(cat $pidfile)
    retval=$?
    echo
    return $retval
}
force_reload() {
    restart
}
fdr_status() {
    status $prog
}
case "$1" in
    start|stop|restart|reload)
        $1
        ;;
    force-reload)
        force_reload
        ;;
    check)
        check
        ;;
    status)
        fdr_status
        ;;
    condrestart|try-restart)
      [ ! -f $lockfile ] || restart
    ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|try-restart|reload|force-reload}"
        exit 2
esac

6.3  keepalived配置文件

主備的配置文件有三點不一樣

router_id不同

優先級不同

state主從不同

其餘都同樣

vim /etc/keepalived/keepalived.conf
#Keepalived配置文件
global_defs {
        router_id NodeA                 #路由ID, 主備的ID不能相同
}
vrrp_instance VI_1 {
        state MASTER #Keepalived的角色。Master表示主服務器,從服務器設置爲BACKUP
        interface eth0          #指定監測網卡
        virtual_router_id 35
        priority 100            #優先級,BACKUP機器上的優先級要小於這個值
        advert_int 1            #設置主備之間的檢查時間,單位爲s
        authentication {        #定義驗證類型和密碼
                auth_type PASS
                auth_pass password123456789
        }
        virtual_ipaddress {     #VIP地址,能夠設置多個:
                192.168.70.35
        }
}
相關文章
相關標籤/搜索