1、RabbitMQ介紹
1.1、什么是RabbitMQ?
RabbitMQ 是由 LShift 提供的一個 Advanced Message Queuing Protocol (AMQP) 的開源實現(xiàn),由以高性能、健壯以及可伸縮性出名的 Erlang 寫成,因此也是繼承了這些優(yōu)點。
1.2、什么是AMQP?
AMQP,即Advanced Message Queuing Protocol,高級消息隊列協(xié)議,是應用層協(xié)議的一個開放標準,為面向消息的中間件設計。它從生產(chǎn)者接收消息并遞送給消費者,在這個過程中,根據(jù)規(guī)則進行路由,緩存與持久化。
AMQP的主要特征是面向消息、隊列、路由(包括點對點和發(fā)布/訂閱)、可靠性、安全。
RabbitMQ是一個開源的AMQP實現(xiàn),服務器端用Erlang語言編寫,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系統(tǒng)中存儲轉(zhuǎn)發(fā)消息,在易用性、擴展性、高可用性等方面表現(xiàn)不俗。
1.3、RabbitMQ的基礎概念
- Broker:簡單來說就是消息隊列服務器實體
- Exchange:消息交換機,它指定消息按什么規(guī)則,路由到哪個隊列
- Queue:消息隊列載體,每個消息都會被投入到一個或多個隊列
- Binding:綁定,它的作用就是把exchange和queue按照路由規(guī)則綁定起來
- Routing Key:路由關鍵字,exchange根據(jù)這個關鍵字進行消息投遞
- vhost:虛擬主機,一個broker里可以開設多個vhost,用作不同用戶的權限分離
- producer:消息生產(chǎn)者,就是投遞消息的程序
- consumer:消息消費者,就是接受消息的程序
- channel:消息通道,在客戶端的每個連接里,可建立多個channel,每個channel代表一個會話任務
1.4、RabbitMQ的特性
- 可靠性:包括消息持久化,消費者和生產(chǎn)者的消息確認
- 靈活路由:遵循AMQP協(xié)議,支持多種Exchange類型實現(xiàn)不同路由策略
- 分布式:集群的支持,包括本地網(wǎng)絡與遠程網(wǎng)絡
- 高可用性:支持主從備份與鏡像隊列
- 多語言支持:支持多語言的客戶端
- WEB界面管理:可以管理用戶權限,exhange,queue,binding,與實時監(jiān)控
- 訪問控制:基于vhosts實現(xiàn)訪問控制
- 調(diào)試追蹤:支持tracing,方便調(diào)試
2、RabbitMQ安裝
2.1、環(huán)境:兩臺Ubuntu16.04主機
10.27.0.53 rabbitmq-1
10.27.0.130 rabbitmq-2
root@rabbitmq-1:/usr/sbin# cat /etc/hosts
10.27.0.53 rabbitmq-1
10.27.0.130 rabbitmq-2
root@rabbitmq-2:/usr/sbin# cat /etc/hosts
10.27.0.53 rabbitmq-1
10.27.0.130 rabbitmq-2
必須保證各個主機名之間可以ping通
2.2、安裝Erlang
root@rabbitmq-1:~# apt-get update
root@rabbitmq-1:~# apt-get install -y erlang-nox erlang-dev erlang-src
2.3、安裝rabbitmq
root@rabbitmq-1:~# echo 'deb http://www.rabbitmq.com/debian/ testing main' | tee /etc/apt/sources.list.d/rabbitmq.list
deb http://www.rabbitmq.com/debian/ testing main
root@rabbitmq-1:~# wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | apt-key add -
--2018-12-13 01:36:08-- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
Resolving www.rabbitmq.com (www.rabbitmq.com)... 104.20.63.197, 104.20.62.197, 2606:4700:10::6814:3ec5, ...
Connecting to www.rabbitmq.com (www.rabbitmq.com)|104.20.63.197|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/plain]
Saving to: ‘STDOUT’
- [ <=> ] 3.11K --.-KB/s in 0s
2018-12-13 01:36:09 (53.9 MB/s) - written to stdout [3187]
OK
root@rabbitmq-1:~# apt-get install rabbitmq-server
2.4、安裝完成后,驗證一下服務是否正常
root@rabbitmq-1:~# service rabbitmq-server start
root@rabbitmq-1:~# service rabbitmq-server status
● rabbitmq-server.service - RabbitMQ broker
Loaded: loaded (/lib/systemd/system/rabbitmq-server.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2018-12-13 01:39:09 UTC; 1min 11s ago
Main PID: 11471 (beam.smp)
Status: "Initialized"
CGroup: /system.slice/rabbitmq-server.service
├─11471 /usr/lib/erlang/erts-7.3/bin/beam.smp -W w -A 64 -P 1048576 -t 5000000 -stbt db -zdbbl 128000 -K true -- -root /usr/lib/erlan
├─11551 /usr/lib/erlang/erts-7.3/bin/epmd -daemon
├─11678 inet_gethost 4
└─11679 inet_gethost 4
搭建好的rabbitmq默認是沒有配置文件的,需要我們來手動添加
root@rabbitmq-1:~# vim /etc/rabbitmq/rabbitmq.config
[{rabbit, [{loopback_users, []}]}].
- 這里的意思是開放使用。rabbitmq默認創(chuàng)建的用戶guest,密碼也是guest,這個用戶默認只能是本機訪問。需要添加上面的配置才能從外部訪問。
Rabbitmq的一些運行腳本存放在 /usr/sbin 下面
root@rabbitmq-1:/usr/sbin# ll rabbit*
-rwxr-xr-x 1 root root 1883 Jan 17 2018 rabbitmqctl*
-rwxr-xr-x 1 root root 1883 Jan 17 2018 rabbitmq-plugins*
-rwxr-xr-x 1 root root 1883 Jan 17 2018 rabbitmq-server*
2.5、開啟web管理插件
2.5.1、創(chuàng)建一個用戶nova,并設置密碼為123456
root@rabbitmq-1:/usr/sbin# ./rabbitmqctl add_user nova 123456
Creating user "nova"
2.5.2、查看現(xiàn)有用戶表
root@rabbitmq-1:/usr/sbin# ./rabbitmqctl list_users
Listing users
rabbit []
guest [administrator] //默認管理員
nova []
這個時候nova用戶是不能訪問web管理插件的,需要配置用戶角色,用戶角色可分為五類,超級管理員, 監(jiān)控者, 策略制定者, 普通管理者以及其他。
- 超級管理員(administrator)
可登陸管理控制臺(啟用management plugin的情況下),可查看所有的信息,并且可以對用戶,策略(policy)進行操作。
- 監(jiān)控者(monitoring)
可登陸管理控制臺(啟用management plugin的情況下),同時可以查看rabbitmq節(jié)點的相關信息(進程數(shù),內(nèi)存使用情況,磁盤使用情況等)
- 策略制定者(policymaker)
可登陸管理控制臺(啟用management plugin的情況下), 同時可以對policy進行管理。但無法查看節(jié)點的相關信息。
- 普通管理者(management)
僅可登陸管理控制臺(啟用management plugin的情況下),無法看到節(jié)點信息,也無法對策略進行管理。
- 其他
無法登陸管理控制臺,通常就是普通的生產(chǎn)者和消費者。
將nova添加到administrator用戶組
root@rabbitmq-1:/usr/sbin# ./rabbitmqctl set_user_tags nova administrator
Setting tags for user "nova" to [administrator]
此時的nova用戶只能通過本地來登錄其他的IP無法直接使用這個賬號。所以需要對他進行授權,使用戶nova /(可以訪問虛擬主機) 中所有資源的配置、寫、讀權限以便管理其中的資源
root@rabbitmq-1:/usr/sbin# ./rabbitmqctl set_permissions -p "/" nova ".*" ".*" ".*"
Setting permissions for user "nova" in vhost "/"
查看用戶授權
root@rabbitmq-1:/usr/sbin# ./rabbitmqctl list_permissions -p /
Listing permissions in vhost "/"
nova .* .* .*
guest .* .* .*
2.5.3、開啟web管理插件并重啟rabbitmq服務
root@rabbitmq-1:/usr/sbin# ./rabbitmq-plugins enable rabbitmq_management
The following plugins have been enabled:
amqp_client
cowlib
cowboy
rabbitmq_web_dispatch
rabbitmq_management_agent
rabbitmq_management
Applying plugin configuration to rabbit@rabbitmq-1... started 6 plugins.
root@rabbitmq-1:/usr/sbin# service rabbitmq-server restart
以下為關閉插件命令
root@rabbitmq-1:/usr/sbin# ./rabbitmq-plugins disable rabbitmq_management
通過瀏覽器訪問 [http://10.27.0.53:15672]輸入用戶名nova 密碼123456就可以看到后臺了

3、配置集群
3.1、從管理界面可以看到,此時只有一個節(jié)點rabbitmq-1,我們需要把rabbitmq-2加進來,rabbitmq-2按照步驟2進行一系列安裝就可以。此處不再細說。

3.2、添加節(jié)點
兩臺主機上安裝的 RabbitMQ 都保證都可以正常啟動,才可以進行以下操作
3.2.1、設置不同節(jié)點間統(tǒng)一認證的Erlang Cookie
這里將 rabbitmq-1 的該文件復制到 rabbitmq-2由于這個文件權限是 400為方便傳輸,先修改權限,非必須操作,所以需要先修改rabbitmq-2中的該文件權限為 777
root@rabbitmq-2:~# chmod 777 /var/lib/rabbitmq/.erlang.cookie
然后將rabbitmq-1中的該文件拷貝的rabbitmq-2中
root@rabbitmq-1:/var/lib/rabbitmq# scp /var/lib/rabbitmq/.erlang.cookie rabbitmq-2:/var/lib/rabbitmq/
最后將權限和所屬用戶/組修改回來
root@rabbitmq-2:~# chmod 400 /var/lib/rabbitmq/.erlang.cookie
root@rabbitmq-2:~# chown rabbitmq /var/lib/rabbitmq/.erlang.cookie
root@rabbitmq-2:~# chgrp rabbitmq /var/lib/rabbitmq/.erlang.cookie
root@rabbitmq-2:~# ll /var/lib/rabbitmq/.erlang.cookie
-r-------- 1 rabbitmq rabbitmq 20 Dec 13 05:37 /var/lib/rabbitmq/.erlang.cookie
此時rabbitmq-2節(jié)點需要重啟一下服務
root@rabbitmq-2:/usr/sbin# service rabbitmq-server restart
注意事項
cookie在所有節(jié)點上必須完全一樣,同步時一定要注意。
erlang是通過主機名來連接服務,必須保證各個主機名之間可以ping通??梢酝ㄟ^編輯/etc/hosts來手工添加主機名和IP對應關系。如果主機名ping不通,rabbitmq服務啟動會失敗。
3.2.2、通過rabbitmqctl cluster_status命令,可以查看和個節(jié)點的狀態(tài),節(jié)點的名稱是rabbit@shorthostname,
rabbitmq-1
root@rabbitmq-1:/usr/sbin# ./rabbitmqctl cluster_status
Cluster status of node 'rabbit@rabbitmq-1'
[{nodes,[{disc,['rabbit@rabbitmq-1']}]},
{running_nodes,['rabbit@rabbitmq-1']},
{cluster_name,<<"rabbit@rabbitmq-1">>},
{partitions,[]},
{alarms,[{'rabbit@rabbitmq-1',[]}]}]
rabbitmq-2
root@rabbitmq-2:/usr/sbin# ./rabbitmqctl cluster_status
Cluster status of node 'rabbit@rabbitmq-2'
[{nodes,[{disc,['rabbit@rabbitmq-2']}]},
{running_nodes,['rabbit@rabbitmq-2']},
{cluster_name,<<"rabbit@rabbitmq-2">>},
{partitions,[]},
{alarms,[{'rabbit@rabbitmq-2',[]}]}]
3.2.3
將兩個節(jié)點組成集群
因為rabbitmq-server啟動時,會一起啟動節(jié)點和應用,它預先設置RabbitMQ應用為standalone模式。要將一個節(jié)點加入到現(xiàn)有的集群中,你需要停止這個應用并將節(jié)點設置為原始狀態(tài),然后就為加入集群準備好了。使用rabbitmqctl stop_app僅僅關閉應用。
root@rabbitmq-2:/usr/sbin# ./rabbitmqctl stop_app
Stopping rabbit application on node 'rabbit@rabbitmq-2'
將2加入1中
root@rabbitmq-2:/usr/sbin# ./rabbitmqctl join_cluster rabbit@rabbitmq-1
Clustering node 'rabbit@rabbitmq-2' with 'rabbit@rabbitmq-1'
啟動節(jié)點2的應用
root@rabbitmq-2:/usr/sbin# ./rabbitmqctl start_app
Starting node 'rabbit@rabbitmq-2'
如果要使用內(nèi)存節(jié)點,則可以使用以下命令:其中–ram指的是作為內(nèi)存節(jié)點,要是想做為磁盤節(jié)點的話,就不用加–ram這個參數(shù)了
root@rabbitmq-2:/usr/sbin# ./rabbitmqctl join_cluster --ram rabbit@ rabbitmq-1
集群配置好后,可以在 RabbitMQ 任意節(jié)點上執(zhí)行 rabbitmqctl cluster_status 來查看是否集群配置成功。
Rabbitmq-1
root@rabbitmq-1:/usr/sbin# ./rabbitmqctl cluster_status
Cluster status of node 'rabbit@rabbitmq-1'
[{nodes,[{disc,['rabbit@rabbitmq-1','rabbit@rabbitmq-2']}]},
{running_nodes,['rabbit@rabbitmq-2','rabbit@rabbitmq-1']},
{cluster_name,<<"rabbit@rabbitmq-1">>},
{partitions,[]},
{alarms,[{'rabbit@rabbitmq-2',[]},{'rabbit@rabbitmq-1',[]}]}]
Rabbitmq-2
root@rabbitmq-2:/usr/sbin# ./rabbitmqctl cluster_status
Cluster status of node 'rabbit@rabbitmq-2'
[{nodes,[{disc,['rabbit@rabbitmq-1','rabbit@rabbitmq-2']}]},
{running_nodes,['rabbit@rabbitmq-1','rabbit@rabbitmq-2']},
{cluster_name,<<"rabbit@rabbitmq-1">>},
{partitions,[]},
{alarms,[{'rabbit@rabbitmq-1',[]},{'rabbit@rabbitmq-2',[]}]}]
同時在Web管理工具中也可以看到效果

4、設置鏡像隊列策略
上面配置RabbitMQ默認集群模式,但并不保證隊列的高可用性,盡管交換機、綁定這些可以復制到集群里的任何一個節(jié)點,但是隊列內(nèi)容不會復制,雖然該模式解決一部分節(jié)點壓力,但隊列節(jié)點宕機直接導致該隊列無法使用,只能等待重啟,所以要想在隊列節(jié)點宕機或故障也能正常使用,就要復制隊列內(nèi)容到集群里的每個節(jié)點,需要創(chuàng)建鏡像隊列。
鏡像隊列概念:鏡像隊列可以同步queue和message,當主queue掛掉,從queue中會有一個變?yōu)橹鱭ueue來接替工作。鏡像隊列是基于普通的集群模式的,所以你還是得先配置普通集群,然后才能設置鏡像隊列。鏡像隊列設置后,會分一個主節(jié)點和多個從節(jié)點,如果主節(jié)點宕機,從節(jié)點會有一個選為主節(jié)點,原先的主節(jié)點起來后會變?yōu)閺墓?jié)點。queue和message雖然會存在所有鏡像隊列中,但客戶端讀取時不論物理面連接的主節(jié)點還是從節(jié)點,都是從主節(jié)點讀取數(shù)據(jù),然后主節(jié)點再將queue和message的狀態(tài)同步給從節(jié)點,因此多個客戶端連接不同的鏡像隊列不會產(chǎn)生同一message被多次接受的情況。
設置鏡像隊列策略
在普通集群的中任意節(jié)點啟用策略,策略會自動同步到集群節(jié)點
命令格式
set_policy [-p vhostpath] {name} {pattern} {definition} [priority]
在任意一個節(jié)點上執(zhí)行
root@rabbitmq-1:/usr/sbin# ./rabbitmqctl set_policy -p / ha-allqueue "^message" '{"ha-mode":"all"}'
Setting policy "ha-allqueue" for pattern "^message" to "{\"ha-mode\":\"all\"}" with priority "0"
集群重啟
集群重啟時,最后一個掛掉的節(jié)點應該第一個重啟,如果因特殊原因(比如同時斷電),而不知道哪個節(jié)點最后一個掛掉。可用以下方法重啟:
先在一個節(jié)點上執(zhí)行
$ ./rabbitmqctl force_boot
$ service rabbitmq-server start
在其他節(jié)點上執(zhí)行
$ ./service rabbitmq-server start
查看cluster狀態(tài)是否正常(要在所有節(jié)點上查詢)。
$ ./rabbitmqctl cluster_status
5、操作授權
添加用戶
處于安全的考慮,guest這個默認的用戶只能通過http://localhost:15672 來登錄,其他的IP無法直接使用這個賬號。所以我們需要添加一個其他用戶。
命令格式
./rabbitmqctl add_user <username> <newpassword>
$ ./rabbitmqctl add_user nova 123456
Creating user "nova"
刪除用戶
命令格式
./rabbitmqctl delete_user <username>
$ ./rabbitmqctl delete_user penglei
Deleting user "penglei"
修改密碼
命令格式
./rabbitmqctl change_password <username> <newpassword>
$ ./rabbitmqctl change_password nova 123456
Changing password for user "nova"
用戶授權
命令格式
./rabbitmqctl set_permissions [-pvhostpath] {user} {conf} {write} {read}
該命令使用戶nova /(可以訪問虛擬主機) 中所有資源的配置、寫、讀權限以便管理其中的資源
$ ./rabbitmqctl set_permissions -p "/"nova ".*" ".*" ".*"
Setting permissions for user "nova" in vhost "/"
查看用戶授權
命令格式
./rabbitmqctl list_permissions [-p VHostPath]
$./ rabbitmqctl list_permissions -p /
Listing permissions in vhost "/"
guest .* .* .*
nova .* .* .*
查看當前用戶列表
可以看到添加用戶成功了,但不是administrator角色
$ ./rabbitmqctl list_users
Listing users
guest [administrator]
nova
添加角色
這里我們也將nova用戶設置為administrator角色
命令格式
./rabbitmqctl set_user_tags <username> <tag>
$ ./rabbitmqctl set_user_tags nova administrator
Setting tags for user "nova" to [administrator]
再次查看權限
$ ./rabbitmqctl list_users
Listing users
guest [administrator]
nova [administrator]
清除權限信息
命令格式
./rabbitmqctl clear_permissions [-p VHostPath] nova
$./rabbitmqctl clear_permissions -p / nova
Clearing permissions for user "nova" in vhost "/"