1. 程式人生 > >Centos7搭建RabbitMQ集群

Centos7搭建RabbitMQ集群

教學 質量 bin log 頁面 www. 字節 text 由於

本片博客簡單介紹rabbitmq單節點以及集群的配置安裝,使用和rabbitmq的命令,和圖形界面簡單的介紹使用


話不多說直接進入正題,首先介紹下rabbitmq:

rabbitmq的歷史:
RabbitMQ是一個由erlang開發的AMQP(Advanced Message Queue )的開源實現。AMQP 的出現其實也是應了廣大人民群眾的需求,雖然在同步消息通訊的世界裏有很多公開標準(如 COBAR的 IIOP ,或者是 SOAP 等),但是在異步消息處理中卻不是這樣,只有大企業有一些商業實現(如微軟的 MSMQ ,IBM 的 Websphere MQ 等),因此,在 2006 年的 6 月,Cisco 、Redhat、iMatix 等聯合制定了 AMQP 的公開標準。

RabbitMQ是由RabbitMQ Technologies Ltd開發並且提供商業支持的。該公司在2010年4月被SpringSource(VMWare的一個部門)收購。在2013年5月被並入Pivotal。其實VMWare,Pivotal和EMC本質上是一家的。不同的是VMWare是獨立上市子公司,而Pivotal是整合了EMC的某些資源,現在並沒有上市。
RabbitMQ的官網是http://www.rabbitmq.com

Rabbitmq是由LShift提供的一個Advanced Message Queuing Protocol(AMQP)的開源實現,由以高性能、健壯、以及可伸縮性出名的Erlang寫成,因此也是繼承了這些優點。

Rabbitmq兩大組件:
Exchange 和 Queue (在 AMQP 1.0 裏還會有變動),如下圖所示,綠色的 X 就是 Exchange ,紅色的是 Queue ,這兩者都在 Server 端,又稱作 Broker ,這部分是 RabbitMQ 實現的,而藍色的則是客戶端,通常有 Producer 和 Consumer 兩種類型:

技術分享圖片

rabbitmq支持兩種協議:

  • AMQP協議:默認
  • MQTT協議:需要手動開啟(下面會介紹如何開啟)

AMQP是什麽:
高級消息隊列協議使得遵從該規範的客戶端應用和消息中間件服務器的全功能互操作成為可能。

AMQP範圍:
為了完全實現消息中間件的互操作性,需要充分定義網絡協議和消息代理服務的功能語義。

因此,AMQP定義網絡協議和代理服務如下:
一套確定的消息交換功能,也就是“高級消息交換協議模型”。AMQP模型包括一套用於路由和存儲消息的功能模塊,以及一套在這些模塊之間交換消息的規則。
一個網絡線級協議(數據傳輸格式),客戶端應用可以通過這個協議與消息代理和它實現的AMQP模型進行交互通信。
可以只實現AMQP協議規範中的的部分語義,但是我們相信明確的描述這些語義有助於理解這個協議


MQTT協議是什麽:
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通訊協議,有可能成為物聯網的重要組成部分。該協議支持所有平臺,幾乎可以把所有聯網物品和外部連接起來,被用來當做傳感器和制動器(比如通過Twitter讓房屋聯網)的通信協議

MQTT協議特點:
為大量計算能力有限,且工作在低帶寬、不可靠的網絡的遠程傳感器和控制設備通訊而設計的協議,它具有以下主要的幾項特性:
1、使用發布/訂閱消息模式,提供一對多的消息發布,解除應用程序耦合;
2、對負載內容屏蔽的消息傳輸;
3、使用 TCP/IP 提供網絡連接;
4、有三種消息發布服務質量:

    “至多一次”,消息發布完全依賴底層 TCP/IP 網絡。會發生消息丟失或重復。這一級別可用於如下情況,環境傳感器數據,丟失一次讀記錄無所謂,因為不久後還會有第二次發送。
    “至少一次”,確保消息到達,但消息重復可能會發生。
    “只有一次”,確保消息到達一次。這一級別可用於如下情況,在計費系統中,消息重復或丟失會導致不正確的結果。

5、小型傳輸,開銷很小(固定長度的頭部是 2 字節),協議交換最小化,以降低網絡流量;
6、使用 Last Will 和 Testament 特性通知有關各方客戶端異常中斷的機制;

註:再使用rabbitmq的時候默認啟用5672端口即AMQP協議,但是部分Android是使用不了AMQP協議的,所以我們要開啟MQTT協議

RabbitMQ的使用場景:
RabbitMQ,或者說AMQP解決了什麽問題,或者說它的應用場景是什麽?
對於一個大型的軟件系統來說,它會有很多的組件或者說模塊或者說子系統或者(subsystem or Component or submodule)。那麽這些模塊的如何通信?這和傳統的IPC有很大的區別。傳統的IPC很多都是在單一系統上的,模塊耦合性很大,不適合擴展(Scalability);如果使用socket那麽不同的模塊的確可以部署到不同的機器上,但是還是有很多問題需要解決。比如:
1)信息的發送者和接收者如何維持這個連接,如果一方的連接中斷,這期間的數據如何方式丟失?
2)如何降低發送者和接收者的耦合度?
3)如何讓Priority高的接收者先接到數據?
4)如何做到load balance?有效均衡接收者的負載?
5)如何有效的將數據發送到相關的接收者?也就是說將接收者subscribe 不同的數據,如何做有效的filter。
6)如何做到可擴展,甚至將這個通信模塊發到cluster上?
7)如何保證接收者接收到了完整,正確的數據?
AMDQ協議解決了以上的問題,而RabbitMQ實現了AMQP。

系統框架:
在這裏rabbitmq的工作原理我就不介紹了,大家想了解的可以去官網看下,這裏給大家提供系統框架圖:
技術分享圖片

RabbitMQ Server: 也叫broker server,它不是運送食物的卡車,而是一種傳輸服務。原話是RabbitMQ isn’t a food truck, it’s a delivery service. 他的角色就是維護一條從Producer到Consumer的路線,保證數據能夠按照指定的方式進行傳輸。但是這個保證也不是100%的保證,但是對於普通的應用來說這已經足夠了。當然對於商業系統來說,可以再做一層數據一致性的guard(保護,防護裝置),就可以徹底保證系統的一致性了。
Client A & B: 也叫Producer,數據的發送方。create messages and publish (send) them to a broker server (RabbitMQ).一個Message有兩個部分:payload(有效載荷)和label(標簽)。payload顧名思義就是傳輸的數據。label是exchange的名字或者說是一個tag,它描述了payload,而且RabbitMQ也是通過這個label來決定把這個Message發給哪個Consumer。AMQP僅僅描述了label,而RabbitMQ決定了如何使用這個label的規則。
Client 1,2,3:也叫Consumer,數據的接收方。Consumers attach to a broker server (RabbitMQ) and subscribe(訂閱) to a queue。把queue比作是一個有名字的郵箱。當有Message到達某個郵箱後,RabbitMQ把它發送給它的某個訂閱者即Consumer。當然可能會把同一個Message發送給很多的Consumer。在這個Message中,只有payload,label已經被刪掉了。對於Consumer來說,它是不知道誰發送的這個信息的。就是協議本身不支持。但是當然了如果Producer發送的payload包含了Producer的信息就另當別論了。

Connection: 就是一個TCP的連接。Producer和Consumer都是通過TCP連接到RabbitMQ Server的。以後我們可以看到,程序的起始處就是建立這個TCP連接。
Channels: 虛擬連接。它建立在上述的TCP連接中。數據流動都是在Channel中進行的。也就是說,一般情況是程序起始建立TCP連接,第二步就是建立這個Channel


介紹完rabbitmq的廢話不多多說直接進入部署rabbitmq集群正題:

在這演示安裝的是yum安裝的,也建議搭建yum安裝,否則erlang環境和rabbtmq的版本問題,可能部署會出問題

安裝基本環境:

yum -y install wget vim bash-completion lrzsz nmap telnet tree net-tools bind-utils lsof ntpdate iotop

準備erlang環境:

wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

安裝rabbitmq:

yum -y install erlang
yum -y install rabbitmq-server

erlang版本:erlang.x86_64 0:R16B-03.18.el7
rabbitmq版本:rabbitmq-server.noarch 0:3.3.5-34.el7

檢查安裝結果:

rpm -qa | grep rabbitmq

啟動和查看狀態:

systemctl status rabbitmq-server                #查看rabbitmq轉態
systemctl start rabbitmq-server                  #啟動rabbitmq
systemctl stop rabbitmq-server                  #關閉rabbitmq

rabbitmq很多情況下使用systemctl restart rabbitmq-server是沒有效果的,必須要stop後在start

開啟Web管理頁面:

rabbitmq-plugins enable rabbitmq_management

開啟MQTT協議:

rabbitmq-plugins enable rabbitmq_mqtt
AMQP協議端口默認:5672
Web頁面默認端口:15672
MQTT協議默認端口:1883
默認登錄用戶名(admin權限):guest
默認登錄密碼:guest

如果想安裝單節點到此就結束了,如果想安裝集群的請繼續往下走


首先講解的是單機多節點部署rabbitmq集群:

首先按照上面的步驟安裝個rabbitmq,在進行一下操作:

確定rabbitmq節點是關閉狀態:
rabbitmqctl stop

方法一:

設置環境變量指定端口和節點名稱:

RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit

後臺啟動節點:

rabbitmq-server -detached

重復上面的操作,但是端口和rabbitmq節點名不可一樣:

RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=rabbit_01
rabbitmq-server -detached
RABBITMQ_NODE_PORT=5674 RABBITMQ_NODENAME=rabbit_02
rabbitmq-server -detached

方法二:
通過編寫主配置文件進行啟動:(rabbitmq默認是沒有主配置文件的)

vim /etc/rabbitmq/rabbitmq-env.conf
NODE_PORT=5672
NODENAME=rabbit
NODE_PORT=5673
NODENAME=rabbit_01
NODE_PORT=5674
NODENAME=rabbit_03
systemctl start rabbitmq-server

不論前面是采用哪種方式,但加入集群的方式一樣的:
先聽掉節點上的應用:

#停掉rabbit_01節點應用
rabbitmqctl -n@localhost rabbit_01 stop_app
#將rabbit_01添加到rabbit節點中
rabbitmqctl -n@localhost rabbit_01 join_cluster rabbit@localhost

#停掉rabbit_02節點應用
rabbitmqctl -n@localhost rabbit_02 stop_app
#將rabbit_02添加到rabbit節點中
rabbitmqctl -n@localhost rabbit_02 join_cluster rabbit@localhost

查看節點信息:

#註:此處只顯示了集群中只有兩個信息,如果按照上面操作添加,會顯示三個節點信息
Cluster status of node rabbit@localhost ...
[{nodes,[{disc,[rabbit@localhost,rabbit_01@localhost]}]},
 {running_nodes,[rabbit@localhost]},
 {cluster_name,<<"rabbit@localhost">>},
 {partitions,[]},
 {alarms,[{rabbit@localhost,[]}]}]

這裏將介紹多節點部署:

*註:多節點不同與單節點的情況,在多機環境,如果要在cluster集群內部署多個節點,需要註意兩個方面:

  • 保證需要部署的這幾個節點在同一個局域網內
  • 需要有相同的Erlang Cookie,否則不能進行通信,為保證cookie的完全一致,采用從一個節點copy的方式

正題:


IP 主機名 rabbitmq節點名
192.168.3.10 node1 rabbitmq1
192.168.3.100 node3 rabbitmq2
192.168.3.205 node4 rabbitmq3

都點尷尬,主機裏面的hosts文件已經配好了,所以難得改了,就這麽用把,但是你們看的時候要註意,我這裏面沒有node2


關閉防火墻,或者配置防火墻規則,否則後面加入集群會出現問題

  1. 配置node1主機hosts文件:(確保可以解析主機名)

    vim /etc/hosts
    192.168.3.10         node1
    192.168.3.100       node3
    192.168.3.205       node4
    scp /etc/hosts [email protected]:/etc/hosts
    scp /etc/hosts [email protected]:/etc/hosts
  2. 安裝rabbitmq(三臺上面同樣操作):

    yum -y install wget vim bash-completion lrzsz nmap telnet tree net-tools bind-utils lsof ntpdate iotop
    wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    yum -y install erlang rabbitmq-server
  3. 配置相同的Erlang Cookie:
    確保三臺的cookie一樣,這樣erlang就處在一個環境中
    首先要啟動rabbitmq,否則沒有cookie,並且cookie是隱藏文件:
    技術分享圖片
    註:三個接單都需要先啟動rabbitmq,然後在關閉

  4. 在node1節點上執行:

    scp /var/lib/rabbitmq/.erlang.cookie root@node3:/var/lib/rabbitmq
    scp /var/lib/rabbitmq/.erlang.cookie root@node4:/var/lib/rabbitmq
  5. 重啟服務看看是否報錯:

    *三個節點都重啟看是否有報錯*
    systemctl stop rabbitmq-server
    systemctl start rabbitmq-server

    註:要是有報錯肯定是.erlang.cookie問題,要麽把.erlang.cookie刪了重新生成,要就看看是否是忘記關閉服務把cookie配置了,一定要註意這些細節性的東西

  6. 將節點加入集群
    #確保服務是啟動的情況下進行
    node3節點上操作
    #將node3加入到node1節點集群中:
    rabbitmqctl stop_app                  #停掉節點服務
    rabbitmqctl reset                         #重置節點配置
    rabbitmqctl join_cluster rabbit@node1  
    # 將node3節點的rabbitmq加入到node1中
    # rabbitmqctl join_cluster rabbit@是固定格式寫法
    rabbitmqctl start_app                  #啟動節點

    技術分享圖片

我們接著講node4也加入node1集群:
技術分享圖片

7.查看集群的狀態:

rabbitmqctl cluster_status

技術分享圖片

註:從中我們可以看出這些幾點都是disc(磁盤節點),我們可以手動把集群節點模式調成內存節點的,當然三臺磁盤節點是最安全的,但是比較浪費資源,正常我們調整為兩臺磁盤一臺內存即可


下面將介紹下如何設置集群的節點模式:
ram:內存
disc:磁盤
默認節點加入集群都是disc節點,設置ram節點兩種方式:
方法一:
加入集群時設置type:

rabbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@node1
rabbitmqctl start_app

方法二:
加入集群後,修改disc節點為ram節點:

rabbitmqctl stop_app
rabbitmqctl change_cluster_node_type ram
rabbitmqctl start_app

我使用了第二種方法將node4從磁盤節點改為內存節點:
技術分享圖片

我們總在命令行裏面操作有時候很難受,所以我們開啟Web點點點模式:(三臺相同操作)

rabbitmq-plugins enable rabbitmq_management
systemctl stop rabbitmq-server
systemctl start rabbitmq-server

查看端口是否起來了,默認端口15672:
技術分享圖片


#三臺相同操作
手動開啟MQTT協議(1883端口),默認只開啟AMQP協議(5672端口)

rabbitmq-plugins enable rabbitmq_mqtt
systemctl stop rabbitmq-server
systemctl start rabbitmq-server

查看端口狀態:

技術分享圖片


集群創建用戶
#只要在一個節點創建即可,都在一個集群中其他前節點都會有這個用戶

rabbitmqctl add_user hcb hcb@pwd                #創建用戶設置密碼
rabbitmqctl set_permissions hcb ".*" ".*" ".*"    #給hcb賦權
rabbitmqctl set_user_tags hcb administrator   #給hcb賦予admin
systemctl restart rabbitmq-server                     #重啟服務

此時我們到web頁面中就可以用這個用戶密碼登錄了

http://192.168.3.10:15672

技術分享圖片
#用默認用戶guest登錄也行,默認也是admin權限

登錄後我們能看到集群的所有信息:
技術分享圖片

在此web如何用我就不多說了都是點點點特別簡單,如果有不會的可以聯系我,現場遠程教學


RabbitMQ負載均衡
選擇開源的HAproxy為rabbitmq集群做負載

安裝epel:

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

安裝HA:

yum -y install haproxy

配置HA:

cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
vim /etc/haproxy/haproxy.cfg

先說下haproxy的配置文件意思:

global           #全局設置
       log 127.0.0.1   local0      #日誌輸出配置,所有日誌都記錄在本機,通過local0輸出
       #log loghost    local0 info
       maxconn 4096             #最大連接數
       chroot /usr/local/haproxy
       uid 99                   #所屬運行的用戶uid
       gid 99                   #所屬運行的用戶組
       daemon                   #以後臺形式運行haproxy
       nbproc 2                 #啟動2個haproxy實例
       pidfile /usr/local/haproxy/haproxy.pid  #將所有進程寫入pid文件
       #debug
       #quiet

defaults             #默認設置
       #log    global
       log     127.0.0.1       local3         #日誌文件的輸出定向
       mode    http         #所處理的類別,默認采用http模式,可配置成tcp作4層消息轉發
       option  httplog       #日誌類別,采用httplog
       option  dontlognull  
       option  forwardfor   #如果後端服務器需要獲得客戶端真實ip需要配置的參數,可以從Http Header中獲得客戶端ip
       option  httpclose    #每次請求完畢後主動關閉http通道,haproxy不支持keep-alive,只能模擬這種模式的實現
       retries 3           #3次連接失敗就認為服務器不可用,主要通過後面的check檢查
       option  redispatch   #當serverid對應的服務器掛掉後,強制定向到其他健康服務器
       maxconn 2000                     #最大連接數
       stats   uri     /haproxy-admin  #haproxy 監控頁面的訪問地址
       contimeout      5000            #連接超時時間
       clitimeout      50000           #客戶端連接超時時間
       srvtimeout      50000           #服務器端連接超時時間
       stats auth  Frank:Frank   #設置監控頁面的用戶和密碼:Frank
stats hide-version         #隱藏統計頁面的HAproxy版本信息

listen rabbitmq_local_cluster VIP:5670 //前段IP,供product和consumer來進行選擇,由於5672端口已經默認使用,這裏選擇5670端口
     mode tcp   //負載均衡選項
     balance roundrobin //輪詢算法將負載發給後臺服務器
     server rabbit 192.168.3.10:5672 check inter 5000 rise 2 fall 3//負載均衡中的集群節點配置,這裏選擇的rabbit節點
     server rabbit 192.168.3.100:5672 check inter 5000 rise 2 fall 3
 server rabbit 192.168.3.205:5672 check inter 5000 rise 2 fall 3

  listen private_monitoring :8100
     mode http
     option httplog
     stats enable
     stats uri       /stats
     stats refresh 60s

#實際配置如:

global
    log 127.0.0.1 local0 info
    maxconn 4096
    stats socket /tmp/haproxy.socket uid haproxy mode 770 level admin
    daemon
defaults
    log global
    mode    tcp
    option  tcplog
    option  dontlognull
    retries 3
    option  redispatch
    maxconn 2000
    timeout connect 5s
    timeout client 120s
    timeout server 120s
listen rabbitmq_local_cluster 0.0.0.0:5670
    mode tcp
    balance roundrobin
    server cacheclod1 192.168.3.10:5672 check inter 5000 rise 2 fall 3
    server cacheclod2 192.168.3.100:5672 check inter 5000 rise 2 fall 3
    server cacheclod3 192.168.3.205:5672 check inter 5000 rise 2 fall 3
listen private_monitoring :8100
    mode http
    option httplog
    stats enable
    stats uri   /stats
    stats refresh 5s

啟動HAproxy:

systemctl start haproxy

查看haproxy控制界面:

http://192.168.3.10:8100/stats

至此rabbitmq介紹完畢,還有好多東西沒有說,比如集群的兩種模式(鏡像模式,普通模式),rabbitmq的配置文件啊,路由機制啊,這些在後面文檔中將會為大家逐一講解,對本片博客有不理解或者發現錯誤的地方歡迎聯系一起探討研究:QQ:1715721936

Centos7搭建RabbitMQ集群