【實踐】docker簡易搭建RabbitMQ集群

RabbitMQ3

1.摘要

本文介紹RabbitMQ搭建普通集群模式和鏡像集群模式的操作指南。

2. 內容

RabbitMQ有2種集群模式,分別是普通集群模式和鏡像集群模式。

第一種 普通集群模式:rabbitmq集群與其他集群有些不同,rabbitmq集群同步的指是復制隊列,元數據信息的同步,即同步的是數據存儲信息;消息的存放只會存儲在創建該消息隊列的那個節點上。并非在節點上都存儲一個完整的數據。在通過非數據所在節點獲取數據時,通過元數據信息,路由轉發到存儲數據節點上,從而得到數據 。

第二種 鏡像集群模式:與普通集群模式區別 主要是消息實體會主動在鏡像節點間同步數據,而不是只存儲數據元信息。 故普通集群模式 但凡數據節點掛了,容易造成數據丟失但鏡像集群模式可以保證集群只要不全部掛掉,數據就不會丟失,當相對于性能來說,鏡像集群模式會比普通集群模式多出消耗數據的傳輸。故取決于業務場景進行取舍。

2.1 普通集群模式

(1)拉取rabbitmq鏡像

在centos窗口中,執行如下命令:

docker pull rabbitmq:3.7-management
1

(2)創建映射數據卷目錄,啟動rabbitmq容器

在centos窗口中,執行如下命令創建文件夾:

mkdir rabbitmqcluster
cd rabbitmqcluster/
mkdir rabbitmq01 rabbitmq02 rabbitmq03

操作日志如下:

[root@localhost rabbitmqcluster]# pwd
/home/soft/
[root@localhost soft]# mkdir rabbitmqcluster
[root@localhost soft]# cd rabbitmqcluster/
[root@localhost rabbitmqcluster]# mkdir rabbitmq01 rabbitmq02 rabbitmq03

注:請讀者自行找尋創建數據映射目錄。
創建完成映射目錄后,在centos窗口中,執行如下命令創建容器:

docker run -d --hostname rabbitmq01 --name rabbitmqCluster01 -v /home/soft/rabbitmqcluster/rabbitmq01:/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' rabbitmq:3.7-management

docker run -d --hostname rabbitmq02 --name rabbitmqCluster02 -v /home/soft/rabbitmqcluster/rabbitmq02:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmqCluster01:rabbitmq01 rabbitmq:3.7-management

docker run -d --hostname rabbitmq03 --name rabbitmqCluster03 -v /home/soft/rabbitmqcluster/rabbitmq03:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmqCluster01:rabbitmq01 --link rabbitmqCluster02:rabbitmq02  rabbitmq:3.7-management

注: --hostname 設置容器的主機名RABBITMQ_ERLANG_COOKIE 節點認證作用,部署集成時 需要同步該值

啟動容器成功后,讀者可以訪問
http://192.168.9.219:15672/#/
http://192.168.9.219:15673/#/
http://192.168.9.219:15674/#/
查看是否正常啟動成功。賬號/密碼:guest / guest
讀者登陸后,查看overview Tab頁,可看到節點信息。

(3)容器節點加入集群

首先在centos窗口中,執行如下命令,進入第一個rabbitmq節點容器:

docker exec -it rabbitmqCluster01 bash

進入容器后,操作rabbitmq,執行如下命令:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit

操作日志信息如下:

[root@localhost rabbitmq01]# docker exec -it rabbitmqCluster01 bash
root@rabbitmq01:/# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq01 ...
root@rabbitmq01:/# rabbitmqctl reset
Resetting node rabbit@rabbitmq01 ...
root@rabbitmq01:/# rabbitmqctl start_app
Starting node rabbit@rabbitmq01 ...
 completed with 3 plugins.
root@rabbitmq01:/# exit
exit

接下來,進入第二個rabbitmq節點容器,執行如下命令:

docker exec -it rabbitmqCluster02 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit

操作日志信息如下:

[root@localhost rabbitmq01]# docker exec -it rabbitmqCluster02 bash
root@rabbitmq02:/# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq02 ...
root@rabbitmq02:/# rabbitmqctl reset
Resetting node rabbit@rabbitmq02 ...
root@rabbitmq02:/# rabbitmqctl join_cluster --ram rabbit@rabbitmq01
Clustering node rabbit@rabbitmq02 with rabbit@rabbitmq01
root@rabbitmq02:/# rabbitmqctl start_app
Starting node rabbit@rabbitmq02 ...
 completed with 3 plugins.
root@rabbitmq02:/# exit
exit

最后,進入第三個rabbitmq節點容器,執行如下命令:

docker exec -it rabbitmqCluster03 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit

操作日志信息如下:

[root@localhost rabbitmq01]# docker exec -it rabbitmqCluster03 bash
root@rabbitmq03:/#  rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq03 ...
root@rabbitmq03:/# rabbitmqctl reset
Resetting node rabbit@rabbitmq03 ...
root@rabbitmq03:/# rabbitmqctl join_cluster --ram rabbit@rabbitmq01
Clustering node rabbit@rabbitmq03 with rabbit@rabbitmq01
root@rabbitmq03:/# rabbitmqctl start_app
Starting node rabbit@rabbitmq03 ...
 completed with 3 plugins.
root@rabbitmq03:/# exit
exit

執行上述操作,這時候 再查看 http://192.168.9.219:15672/#/ 的overview面板中的Nodes信息,可查看到節點信息。

在這里插入圖片描述

(4)負載均衡設置

有了集群之后 還要設置負載均,為了防止出現對單一節點造成高負載的情況。
本次測試用例 采用nginx中間件。讀者可根據自身需要進行選擇。

1. 配置nginx_rabbitmq.conf信息
本機上存放著一個nginx配置文件:/home/soft/nginx/nginx_rabbitmq.conf

nginx_rabbitmq.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    
    proxy_redirect          off;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size    10m;
    client_body_buffer_size   128k;
    proxy_connect_timeout   5s;
    proxy_send_timeout      5s;
    proxy_read_timeout      5s;
    proxy_buffer_size        4k;
    proxy_buffers           4 32k;
    proxy_busy_buffers_size  64k;
    proxy_temp_file_write_size 64k;
    #rabbitmq管理界面
    upstream rabbitManage {
        server 192.168.9.219:15672;
        server 192.168.9.219:15673;
        server 192.168.9.219:15674;
    }
    server {
        listen       15675;
        server_name  192.168.9.219; 
        location / {  
            proxy_pass   http://rabbitManage;
            index  index.html index.htm;  
        }  

    }
}
# rabbitmq通信
stream{
    upstream rabbitTcp{
        server 192.168.9.219:5672;
        server 192.168.9.219:5673;
        server 192.168.9.219:5674;
    }

    server {
        listen 5675;
        proxy_pass rabbitTcp;
    }
}

注:這里配置rabbitmq管理界面 以及通信反向代理

2.啟動nginx容器

在centos窗口中,執行如下命令:

docker run -it -d --name nginxRabbitmq -v /home/soft/nginx/nginx_rabbitmq.conf:/etc/nginx/nginx.conf  --privileged --net=host nginx

接著讀者可以通過 http://192.168.9.219:15675 進行管理 以及通過 5675 端口 進行rabbitmq通信。

2.2 鏡像集群

跟第一種 普通集群模式相比,該模式加入鏡像隊列供,以及加入keepalived實現HA高可用進行容災。
架構圖如下:

在這里插入圖片描述

(1)拉取鏡像

https://hub.docker.com/_/rabbitmq?tab=tags&page=1&ordering=last_updated 網址獲取需要的RabbitMQ版本號。

在Ubuntu窗口中,執行如下命令:

docker pull rabbitmq:3.8.11-management

(2)創建映射數據卷目錄,啟動rabbitmq容器

在shell命令窗口執行如下命令創建文件夾:

mkdir rabbitmqcluster
cd rabbitmqcluster/
mkdir rabbitmq01 rabbitmq02 rabbitmq03

注:請讀者自行找尋創建數據映射目錄,例如pwd得到輝哥的大目錄為/home/datadisk/rabbitmq/rabbitmqcluster 。

創建完成映射目錄后,在centos窗口中,執行如下命令創建容器:

docker run -d --hostname rabbitmq01 --name rabbitmqCluster01 -v /home/datadisk/rabbitmq/rabbitmqcluster/rabbitmq01:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' rabbitmq:3.8.11-management

docker run -d --hostname rabbitmq02 --name rabbitmqCluster02 -v /home/datadisk/rabbitmq/rabbitmqcluster/rabbitmq02:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmqCluster01:rabbitmq01 rabbitmq:3.8.11-management

docker run -d --hostname rabbitmq03 --name rabbitmqCluster03 -v /home/datadisk/rabbitmq/rabbitmqcluster/rabbitmq03:/var/lib/rabbitmq -p 15675:15672 -p 5675:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmqCluster01:rabbitmq01 --link rabbitmqCluster02:rabbitmq02  rabbitmq:3.8.11-management

注: --hostname 設置容器的主機名RABBITMQ_ERLANG_COOKIE 節點認證作用,部署集成時 需要同步該值

說明:如果安全組的端口關閉的話,記得打開公有云安全組和寶塔中的15673,15674,15675的端口號。

啟動容器成功后,讀者可以訪問
http://114.67.117.226:15673/#/
http://114.67.117.226:15674/#/
http://114.67.117.226:15675/#/

查看是否正常啟動成功。賬號/密碼:guest / guest
讀者登陸后,查看overview Tab頁,可看到節點信息。

(3)容器節點加入集群

<1> 首先在shell窗口中,執行如下命令,進入第一個rabbitmq節點容器:

docker exec -it rabbitmqCluster01 bash

進入容器后,操作rabbitmq,執行如下命令:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit

<2> 接下來,進入第二個rabbitmq節點容器,執行如下命令:

docker exec -it rabbitmqCluster02 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit

<3> 緊接著,進入第三個rabbitmq節點容器,執行如下命令:

docker exec -it rabbitmqCluster03 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit

rabbitmqctl join_cluster {cluster_node} [–ram]表示將節點加入指定集群中。在這個命令執行前需要停止RabbitMQ應用并重置節點。參數“--ram”表示同步 rabbit@rabbitmq01的內存節點,忽略次參數默認為磁盤節點。

經過以上3步,組件了3個節點的集群。

<4> 最后,實現鏡像模式集群。進入rabbitmqCluster01容器中

docker exec -it rabbitmqCluster01 bash

執行如下命令:

rabbitmqctl set_policy -p / ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

這行命令在vhost名稱為/創建了一個策略,策略名稱為ha-all,策略模式為 all 即復制到所有節點,包含新增節點,策略正則表達式為 “^” 表示所有匹配所有隊列名稱

<1> RabbitMQ鏡像策略set_policy

添加vhosts

 rabbitmqctl add_vhost <vhost>
 rabbitmqctl delete_vhost <vhost>
 rabbitmqctl list_vhosts [<vhostinfoitem> ...]

參數設置格式:

#設置
rabbitmqctl set_policy [-p <vhost>] [--priority <priority>] [--apply-to <apply-to>] <name> <pattern>  <definition>

#清除
rabbitmqctl clear_policy [-p <vhost>] <name>

#查看
rabbitmqctl list_policies [-p <vhost>]

例如:

##set_policy
rabbitmqctl set_policy -p vh_test1 ha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

Setting policy "ha" for pattern "^" to "{\"ha-mode\":\"all\",\"ha-sync-mode\":\"automatic\"}" with priority "0"


##list_policies
rabbitmqctl list_policies -p vh_test1

Listing policies
vh_test1    ha  all ^   {"ha-mode":"all","ha-sync-mode":"automatic"}    0

##clear_policy
rabbitmqctl clear_policy -p vh_test1 ha

Clearing policy "ha"

參數
[1] ha-mode:策略鍵
1.all 隊列鏡像在群集中的所有節點上。當新節點添加到群集時,隊列將鏡像到該節點
2.exactly 集群中的隊列實例數。
3.nodes 隊列鏡像到節點名稱中列出的節點。

[2] ha-sync-mode:隊列同步
1.manual手動<默認模式>.新的隊列鏡像將不會收到現有的消息,它只會接收新的消息。
2.automatic自動同步.當一個新鏡像加入時,隊列會自動同步。隊列同步是一個阻塞操作。

為用戶賦權:
rabbitmqctl set_permissions -p /vhost1 user_admin '.*' '.*' '.*'
該命令使用戶user_admin具有/vhost1這個virtual host中所有資源的配置、寫、讀權限以便管理其中的資源

執行上述操作,這時候 再查看 http://114.67.117.226:15673/#/ 的overview面板中的Nodes信息,可查看到節點信息。

6.集群節點信息

(4)負載均衡設置

有了集群之后 還要設置負載均,為了防止出現對單一節點造成高負載的情況。
本次測試用例 采用nginx中間件。讀者可根據自身需要進行選擇。

<1> 本機上存放著兩個nginx配置文件

增加nginx目錄,增加配置文件后,用docker啟動NGINX反向代理。

/home/datadisk/nginx/nginx_rabbitmq_1.conf
nginx_rabbitmq_1.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    
    proxy_redirect          off;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size    10m;
    client_body_buffer_size   128k;
    proxy_connect_timeout   5s;
    proxy_send_timeout      5s;
    proxy_read_timeout      5s;
    proxy_buffer_size        4k;
    proxy_buffers           4 32k;
    proxy_busy_buffers_size  64k;
    proxy_temp_file_write_size 64k;
    #rabbitmq管理界面
    upstream rabbitManage {
        server 114.67.117.226:15673;
        server 114.67.117.226:15674;
        server 114.67.117.226:15675;
    }
    server {
        listen       15676;
        server_name   114.67.117.226; 
        location / {  
            proxy_pass   http://rabbitManage;
            index  index.html index.htm;  
        }  

    }
}
# rabbitmq通信
stream{
    upstream rabbitTcp{
        server 114.67.117.226:5673;
        server 114.67.117.226:5674;
        server 114.67.117.226:5675;
    }

    server {
        listen 5676;
        proxy_pass rabbitTcp;
    }
}

/home/datadisk/nginx/nginx_rabbitmq_2.conf
nginx_rabbitmq_2.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    
    proxy_redirect          off;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size    10m;
    client_body_buffer_size   128k;
    proxy_connect_timeout   5s;
    proxy_send_timeout      5s;
    proxy_read_timeout      5s;
    proxy_buffer_size        4k;
    proxy_buffers           4 32k;
    proxy_busy_buffers_size  64k;
    proxy_temp_file_write_size 64k;
    #rabbitmq管理界面
    upstream rabbitManage {
        server 114.67.117.226:15673;
        server 114.67.117.226:15674;
        server 114.67.117.226:15675;
    }
    server {
        listen       15677;
        server_name   114.67.117.226; 
        location / {  
            proxy_pass   http://rabbitManage;
            index  index.html index.htm;  
        }  

    }
}
# rabbitmq通信
stream{
    upstream rabbitTcp{
        server 114.67.117.226:5673;
        server 114.67.117.226:5674;
        server 114.67.117.226:5675;
    }

    server {
        listen 5677;
        proxy_pass rabbitTcp;
    }
}

注:這里配置rabbitmq管理界面 以及通信反向代理

<2> 啟動兩個nginx容器

在centos窗口中,執行如下命令:

docker run -it -d --name nginxRabbitmq1 -v /home/datadisk/nginx/nginx_rabbitmq_1.conf:/etc/nginx/nginx.conf  --privileged --net=host nginx

docker run -it -d --name nginxRabbitmq2 -v /home/datadisk/nginx/nginx_rabbitmq_2.conf:/etc/nginx/nginx.conf  --privileged --net=host nginx

完成nginx的配置。如果docker本地沒有NGIX,則會先自動從倉庫pull最新的nginx鏡像。

這時候 可以通過訪問 http://114.67.117.226:15676/#/ 以及 http://114.67.117.226:15677 進行測試。是否搭建成功。

(5)安裝keepalived 實現HA

<1> Keepalived說明

Keepalive簡介

Keepalived是Linux下一個輕量級別的高可用解決方案。高可用(High Avalilability,HA),其實兩種不同的含義:廣義來講,是指整個系統的高可用行,狹義的來講就是之主機的冗余和接管,

它與HeartBeat RoseHA 實現相同類似的功能,都可以實現服務或者網絡的高可用,但是又有差別,HeartBeat是一個專業的、功能完善的高可用軟件,它提供了HA 軟件所需的基本功能,比如:心跳檢測、資源接管,檢測集群中的服務,在集群節點轉移共享IP地址的所有者等等。HeartBeat功能強大,但是部署和使用相對比較麻煩,

與HeartBeat相比,Keepalived主要是通過虛擬路由冗余來實現高可用功能,雖然它沒有HeartBeat功能強大,但是Keepalived部署和使用非常的簡單,所有配置只需要一個配置文件即可以完成,

Keepalived起初是為LVS設計的,專門用來監控集群系統中各個服務節點的狀態,它根據TCP/IP參考模型的第三、第四層、第五層交換機制檢測每個服務節點的狀態,如果某個服務器節點出現異常,或者工作出現故障,Keepalived將檢測到,并將出現的故障的服務器節點從集群系統中剔除,這些工作全部是自動完成的,不需要人工干涉,需要人工完成的只是修復出現故障的服務節點。

后來Keepalived又加入了VRRP的功能,VRRP(Vritrual Router Redundancy Protocol,虛擬路由冗余協議)出現的目的是解決靜態路由出現的單點故障問題,通過VRRP可以實現網絡不間斷穩定運行,因此Keepalvied 一方面具有服務器狀態檢測和故障隔離功能,另外一方面也有HA cluster功能,下面介紹一下VRRP協議實現的過程。

VRRP協議與工作原理

在現實的網絡環境中。主機之間的通信都是通過配置靜態路由或者(默認網關)來完成的,而主機之間的路由器一旦發生故障,通信就會失效,因此這種通信模式當中,路由器就成了一個單點瓶頸,為了解決這個問題,就引入了VRRP協議。

熟悉網絡的學員對VRRP協議應該不陌生,它是一種主備模式的協議,通過VRRP可以在網絡發生故障時透明的進行設備切換而不影響主機之間的數據通信,這其中涉及到兩個概念:物理路由器和虛擬路由器。

VRRP可以將兩臺或者多臺物理路由器設備虛擬成一個虛擬路由,這個虛擬路由器通過虛擬IP(一個或者多個)對外提供服務,而在虛擬路由器內部十多個物理路由器協同工作,同一時間只有一臺物理路由器對外提供服務,這臺物理路由設備被成為:主路由器(Master角色),一般情況下Master是由選舉算法產生,它擁有對外服務的虛擬IP,提供各種網絡功能,如:ARP請求,ICMP 數據轉發等,而且其它的物理路由器不擁有對外的虛擬IP,也不提供對外網絡功能,僅僅接收MASTER的VRRP狀態通告信息,這些路由器被統稱為“BACKUP的角色”,當主路由器失敗時,處于BACKUP角色的備份路由器將重新進行選舉,產生一個新的主路由器進入MASTER角色,繼續提供對外服務,整個切換對用戶來說是完全透明的。

每個虛擬路由器都有一個唯一的標識號,稱為VRID,一個VRID與一組IP地址構成一個虛擬路由器,在VRRP協議中,所有的報文都是通過IP多播方式發送的,而在一個虛擬路由器中,只有處于Master角色的路由器會一直發送VRRP數據包,處于BACKUP角色的路由器只會接受Master角色發送過來的報文信息,用來監控Master運行狀態,一一般不會發生BACKUP搶占的情況,除非它的優先級更高,而當MASTER不可用時,BACKUP也就無法收到Master發過來的信息,于是就認定Master出現故障,接著多臺BAKCUP就會進行選舉,優先級最高的BACKUP將稱為新的MASTER,這種選舉角色切換非常之快,因而保證了服務的持續可用性。

Keepalvied的工作原理

上面我們介紹了Keepalived通過VRRP實現高可用性的工作原理,而Keepalived作為一個高性能集群軟件,它還能實現對集群中服務器運行狀態的監控以及故障隔離,下面我們介紹一下Keepalived對服務器運行狀態和故障隔離的工作原理。

Keepalived工作在TCP/IP 參考模型的 三層、四層、五層,也就是分別為:網絡層,傳輸層和應用層,根據TCP、IP參數模型隔層所能實現的功能,Keepalived運行機制如下:

在網絡層:我們知道運行這4個重要的協議,互聯網絡IP協議,互聯網絡可控制報文協議ICMP、地址轉換協議ARP、反向地址轉換協議RARP,在網絡層Keepalived在網絡層采用最常見的工作方式是通過ICMP協議向服務器集群中的每一個節點發送一個ICMP數據包(有點類似與Ping的功能),如果某個節點沒有返回響應數據包,那么認為該節點發生了故障,Keepalived將報告這個節點失效,并從服務器集群中剔除故障節點。

在傳輸層:提供了兩個主要的協議:傳輸控制協議TCP和用戶數據協議UDP,傳輸控制協議TCP可以提供可靠的數據輸出服務、IP地址和端口,代表TCP的一個連接端,要獲得TCP服務,需要在發送機的一個端口和接收機的一個端口上建立連接,而Keepalived在傳輸層里利用了TCP協議的端口連接和掃描技術來判斷集群節點的端口是否正常,比如對于常見的WEB服務器80端口。或者SSH服務22端口,Keepalived一旦在傳輸層探測到這些端口號沒有數據響應和數據返回,就認為這些端口發生異常,然后強制將這些端口所對應的節點從服務器集群中剔除掉。

在應用層:可以運行FTP,TELNET,SMTP,DNS等各種不同類型的高層協議,Keepalived的運行方式也更加全面化和復雜化,用戶可以通過自定義Keepalived工作方式,例如:可以通過編寫程序或者腳本來運行Keepalived,而Keepalived將根據用戶的設定參數檢測各種程序或者服務是否允許正常,如果Keepalived的檢測結果和用戶設定的不一致時,Keepalived將把對應的服務器從服務器集群中剔除。

Keepalived體系結構

img

keepalived也是模塊化設計,不同模塊復雜不同的功能,它主要有三個模塊,分別是core、check和VRRP,其中:
core模塊:為keepalived的核心組件,負責主進程的啟動、維護以及全局配置文件的加載和解析;
check:負責健康檢查,包括常見的各種檢查方式;
VRRP模塊:是來實現VRRP協議的。

system call:系統調用
watch dog:監控check和vrrp進程的看管者,check負責檢測器子進程的健康狀態,當其檢測到master上的服務不可用時則通告vrrp將其轉移至backup服務器上。

除此之外,keepalived還有下面兩個組件:
libipfwc:iptables(ipchains)庫,配置LVS會用到
libipvs*:配置LVS會用到
注意,keepalived和LVS完全是兩碼事,只不過他們各負其責相互配合而已。

keepalived正常啟動的時候,共啟動3個進程:
一個是父進程,負責監控其子進程;一個是VRRP子進程,另外一個是checkers子進程;
兩個子進程都被系統watchlog看管,兩個子進程各自負責復雜自己的事。
Healthcheck子進程檢查各自服務器的健康狀況,,例如http,lvs。如果healthchecks進程檢查到master上服務不可用了,就會通知本機上的VRRP子進程,讓他刪除通告,并且去掉虛擬IP,轉換為BACKUP狀態。

Keepalived作用:
Keepalived主要用作RealServer的健康狀態檢查以及LoadBalance主機和BackUP主機之間failover的實現。Keepalived的作用是檢測web服務器的狀態,如果有一臺web服務器死機,或工作出現故障,Keepalived將檢測到,并將有故障的web服務器從系統中剔除,當web服務器工作正常后Keepalived自動將web服務器加入到服務器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修復故障的web服務器。

<2> 啟動keepalived

【以下內容實際未執行成功,無法實現高可用。以后有空再嘗試。需要特別明白keepalived的參數意思。】

在兩個nginx容器分別安裝keepalived,并編寫keepalived配置文件以及啟動keepalived。

1.1 進入nginxRabbitmq1容器中,執行如下命令:

docker exec -it nginxRabbitmq1 bash
apt-get  -y update
apt-get -y  install vim
apt-get -y install keepalived

安裝完成后,編寫keekpalived.conf,

vim /etc/keepalived/keepalived.conf

內容如下:

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
       114.67.117.227
    }
}
virtual_server  114.67.117.227 15678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server  114.67.117.226 15676 {
        weight 1
    }
}
virtual_server 114.67.117.227 5678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 114.67.117.226 5676 {
        weight 1
    }
}

保存完配置,啟動keepalived

service keepalived start

注:interface 表示綁定的網絡接口,請用ip addr 查看本機的網卡進行替換 ,virtual_router_id 表示keepalived家族標識信息,全局唯一,節點間保持相同

在主機命令行下允許以下命令可以查看容器內啟動的進程:

docker top nginxRabbitmq1

1.2 進入nginxRabbitmq2容器中,執行如下命令:

docker exec -it nginxRabbitmq2 bash
apt-get  -y update
apt-get -y  install vim
apt-get -y install keepalived

安裝完成后,編寫keekpalived.conf,

vim /etc/keepalived/keepalived.conf

內容如下:

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
       114.67.117.228
    }
}
virtual_server  114.67.117.228 15678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server  114.67.117.226 15677 {
        weight 1
    }
}
virtual_server 114.67.117.228 5678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 114.67.117.226 5677 {
        weight 1
    }
}

保存完配置,啟動keepalived

service keepalived start

(6)主機上安裝keepaplived進行轉發

在shell窗口中,執行如下命令:

apt-get -y install keepalived

安裝完成后,編寫配置文件keepalived.conf

vim /etc/keepalived/keepalived.conf

內容如下:

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
       114.67.117.228
    }
}
virtual_server  114.67.117.228 15678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 114.67.117.227 15676 {
        weight 1
    }
    real_server 114.67.117.227 15677{
        weight 1
    }
}
virtual_server 114.67.117.228 5678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 114.67.117.227 5676 {
        weight 1
    }
    real_server 114.67.117.227 5677 {
        weight 1
    } 
}

保存完配置后,啟動keepalived

service keepalived start

接著讀者可以通過http://114.67.117.226:15678進行管理 以及通過 5678 端口 進行rabbitmq通信。
可以測試停止nginxRabbitmq1或者nginxRabbitmq2進行測試,本文就不再贅述測試過程。

(7)keepalived配置文件部分說明

vrrp_instance VI_1 {              --- vrrp協議相關配置(vip地址設置)

    state MASTER                  --- keepalived角色描述(狀態)信息,可以配置參數(MASTER BACKUP)

    interface eth0                --- 表示將生成虛IP地址,設置在指定的網卡上(一般為外網卡)

    virtual_router_id 51          --- 表示keepalived家族標識信息

    priority 100                  --- keepalived服務競選主備服務器優先級設置(越大越優先)

    advert_int 1                  --- 主服務組播包發送間隔時間       

    authentication {              --- 主備主機之間通訊認證機制,

        auth_type PASS            --- 采用明文認證機制

        auth_pass 123456            --- 編寫明文密碼(用于主備認證)

    }

    virtual_ipaddress {           --- 設置虛擬IP地址信息

       192.168.44.130

    }
   virtual_server 192.168.44.130 15678 {  --- 設置虛擬IP地址 端口轉發
   
      delay_loop 3                    ---- service polling的delay時間,即服務輪詢的時間間隔
    
      lb_algo rr                     --- LVS調度算法 
      
      lb_kind NAT                    --- LVS集群模式  
    
      persistence_timeout 50          --- 會話保持時間(秒為單位),即以用戶在120秒內被分配到同一個后端realserver
    
      protocol TCP                    --- 健康檢查用的是TCP還是UDP
    
      real_server 192.168.9.144 15676 {
        
           weight 1                   --- 給每臺的權重,0表示失效(不知給他轉發請求知道他恢復正常),默認是1
   
     }
  }

}

3.參考

(1)RabbitMQ 高可用集群搭建【優質】
https://blog.csdn.net/qq_28533563/article/details/107932737

(2)docker簡易搭建RabbitMQ集群【優質】

https://blog.csdn.net/belonghuang157405/article/details/83540148

(2) docker安裝RabbitMQ

https://blog.csdn.net/weixin_40009737/article/details/112004194

(2)Docker下配置KeepAlive支持nginx高可用

https://www.cnblogs.com/jake-jin/p/12713324.html

(2)消息中間件—RabbitMQ(集群原理與搭建篇)
http://www.lxweimin.com/p/6376936845ff

(3)RabbitMQ系列(九)分布式RabbitMQ概述
https://juejin.cn/post/6844904066452029454

(4)RabbitMQ系列(十)分布式RabbitMQ(集群)
https://juejin.cn/post/6844904071183220749

(5)RabbitMQ系列(十一)分布式RabbitMQ(隊列鏡像)
https://juejin.cn/post/6844904072303116302

(6)RabbitMQ系列(十二)基于RabbitMQ的分布式事務
https://juejin.cn/post/6844904147418873864

(9)RabbitMQ官方文檔搜"Distributed RabbitMQ"

https://www.rabbitmq.com/documentation.html

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。