rabbitMQ學習筆記html
2017年12月31日星期日 Leenode
環境:centos7 linux
版本:rabbitmq-server-3.7.2-1git
準備了3臺主機作實驗。先配置hosts以下。github
cat /etc/hostsweb
192.168.5.71 node1數據庫
192.168.5.72 node72vim
192.168.5.73 node73centos
建議看下美團分享的rabbitmq基礎:http://mp.weixin.qq.com/s/OABseRR0BnbK9svIPyLKXw瀏覽器
AMQP三個組件:交換器、隊列、綁定
處理流程:消息 ---> 交換器 ---> Client
交換器的4種類型:
direct 根據路由鍵投遞消息
fanout 廣播方式,綁定到同一個exchange上的queue都能收到一樣的msg。不須要路由鍵,若是接受到消息的Exchange沒有與任何Queue綁定,則消息會被拋棄
topic 根據queue定義的topic名稱來接收相應的msg
header (不多用,直接忽略它)
虛擬主機vhost:
每一個vhost至關於一個mini的rabbitmq服務器,有獨立的權限控制機制。不一樣的vhost能夠存在同名的交換器和隊列名。
在rabbitmq中,權限控制是以vhost爲單位的。
rabbitmqctl [add_vhost|delete_vhost] vhost1 便可添加/刪除一個名爲vhost1的虛擬主機
消息確認機制:
RabbitMQ提供了transaction、confirm兩種消息確認機制。
transaction即事務機制,手動提交和回滾;
confirm機制提供了Confirmlistener和waitForConfirms兩種方式。
confirm機制效率明顯會高於transaction機制,但transaction的優點在於強一致性。若是沒有特別的要求,建議使用conrim機制。
1、從實驗來看,消息的確認機制只是確認publisher發送消息到broker,由broker進行應答,不能確認消息是否有效消費。
2、而爲了確認消息是否被髮送給queue,應該在發送消息中啓用參數mandatory=true,使用ReturnListener接收未被髮送成功的消息。
3、接下來就須要確認消息是否被有效消費。publisher端目前並無提供監聽事件,但提供了應答機制來保證消息被成功消費,應答方式:
basicAck:成功消費,消息從隊列中刪除
basicNack:requeue=true,消息從新進入隊列,false被刪除
basicReject:等同於basicNack
basicRecover:消息重入隊列,requeue=true,發送給新的consumer,false發送給相同的consumer
發送方確認機制:
客戶端發送請求(消息)時,在消息的屬性(Message Properties,在AMQP協議中定義了14種properties,這些屬性會隨着消息一塊兒發送)中設置兩個值replyTo(一個Queue名稱,用於告訴服務器處理完成後將通知個人消息發送到這個Queue中)和correlationId(這次請求的標識號,服務器處理完成後須要將此屬性返還,客戶端將根據這個id瞭解哪條請求被成功執行了或執行失敗)。服務器端收到消息處理完後,將生成一條應答消息到replyTo指定的Queue,同時帶上correlationId屬性。客戶端以前已訂閱replyTo指定的Queue,從中收到服務器的應答消息後,根據其中的correlationId屬性分析哪條請求被執行了,根據執行結果進行後續業務處理。
erlang節點:
erlang相似JVM,erlang節點能自動嘗試啓動所在節點的應用程序。
在node1上執行以下的操做步驟:
yum localinstall rabbitmq-server-3.7.2-1.el7.noarch.rpm erlang-19.3.6.5-1.el7.centos.x86_64.rpm -y
rpm -qpl rabbitmq-server-3.7.2-1.el7.noarch.rpm | less 能夠列出rabbitmq的軟件釋放文件路徑,以下:
/etc/rabbitmq
/usr/lib/rabbitmq/
/var/lib/rabbitmq
cp /usr/share/doc/rabbitmq-server-3.7.2/rabbitmq.config.example /etc/rabbitmq/
cd /etc/rabbitmq/
mv rabbitmq.config.example rabbitmq.config
vim rabbitmq.config 開啓部分註釋後,具體取消註釋的地方以下:
[
{rabbit,
[
{tcp_listeners, [5672]},
{loopback_users, []}
]}
].
systemctl start rabbitmq-server 或者使用rabbitmq-server -detached 這種啓動方式
經常使用命令:
rabbitmqctl status 列出rabbitmq的運行狀態,版本信息等很是多的運行參數
列出隊列狀況
[root@node1 /root ]# rabbitmqctl list_queues
Timeout: 60.0 seconds ...
Listing queues for vhost / ...
查看當前exchanges的狀況
[root@node1 /root ]# rabbitmqctl list_exchanges
Listing exchanges for vhost / ...
amq.fanout fanout
amq.match headers
amq.direct direct
amq.rabbitmq.log topic
amq.topic topic
amq.rabbitmq.trace topic
amq.headers headers
direct
查看bingding,剛安裝服務的時候也沒有binding
[root@node1 /root ]# rabbitmqctl list_bindings
Listing bindings for vhost /...
列出用戶
[root@node1 /root ]# rabbitmqctl list_users
Listing users ...
guest [administrator]
列出vhosts
[root@node1 /root ]# rabbitmqctl list_vhosts
Listing vhosts ...
/
添加用戶
[root@node1 /root ]# rabbitmqctl add_user ops 123456
Adding user "ops" ...
修改密碼
[root@node1 /root ]# rabbitmqctl change_password ops 12345678
設置用戶權限
[root@node1 /root ]# rabbitmqctl set_user_tags ops administrator
Setting tags for user "ops" to [administrator] ...
刪除用戶(會連帶這個帳戶相關的訪問控制條目都刪掉)
[root@node1 /root ]# rabbitmqctl delete_user ops
Deleting user "ops" ...
列出有哪些插件
[root@node1 /root ]# rabbitmq-plugins list
安裝管控頁面【web管理頁面】
rabbitmq-plugins enable rabbitmq_management
卸載插件
rabbitmq-plugins disable xxxxx
中止rabbitmq程序及節點(erlang)
rabbitmqctl stop
單獨中止rabbitmq
rabbitmqctl stop_app
中止遠程節點:
rabbitmqctl stop -n rabbit@[remote_hostname]
啓動rabbitmq-server後執行rabbitmq-plugins enable rabbitmq_management安裝web管理插件,而後在瀏覽器訪問
http://192.168.5.71:15672/
默認用戶名和密碼都是guest
單節點不多用,所以這裏一些命令就不說了, 統一放到後面集羣環境下說。
在node72和node73上安裝rabbitmq,啓動rabbitmq進程,而後安裝好rabbitmq_management插件。
rpm包安裝的rabbitmq在 /var/lib/rabbitmq/ 路徑下,有一個 .erlang.cookie的文件。
在node1上執行:
cd /var/lib/rabbitmq/
chmod u+w .erlang.cookie
scp .erlang.cookie root@node72:/var/lib/rabbitmq/
scp .erlang.cookie root@node73:/var/lib/rabbitmq/
而後執行 rabbitmqctl cluster_status 能夠看到cluster_name 集羣的名稱。
在3臺主機都上執行:
rabbitmqctl stop // 執行這個命令確保rabbitmq進程是中止狀態的
rabbitmq-server -detached // 使用-detached參數後臺啓動tabbitmq
而後在node72和node73上執行以下命令,將其加入到node1的集羣環境中:
rabbitmqctl stop_app
rabbitmqctl reset // (可選)第一次加入集羣的新主機的話,建議執行下reset這個命令 清空節點的狀態
rabbitmqctl join_cluster rabbit@node1
rabbitmqctl start_app
這時候,再到node1上執行rabbitmqctl cluster_status 能夠看到集羣running node信息
再web節目也有顯示了:
3.1 配置鏡像隊列:
在任意一個節點上執行:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' -p /
這個命令會將/ 這個vhost的全部隊列設置爲鏡像隊列,即隊列會被複制到各個節點,各個節點狀態保持一致。
rabbitmqctl add_vhost vh4
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' -p vh4
這個命令會將vh4 這個vhost的全部隊列設置爲鏡像隊列,即隊列會被複制到各個節點,各個節點狀態保持一致。
至此,RabbitMQ 高可用集羣就已經搭建好了,最後一個步驟就是搭建均衡器
3.2 查看vhost名爲vh3的所有鏡像隊列是否同步完成:
rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids -p vh3
如上圖,兩個紅色框內的信息如出一轍,說明全部的slave隊列裏的數據都同步了。這樣的話,咱們才能放心的剔除某個節點且保證數據不丟失。
3.3 鏡像隊列節點宕機的狀況:
若是鏡像隊列丟失了一個從節點,則對任何消費者都不會有影響。
主節點宕機,集羣內部會從新選主。消費者須要從新附加到主隊列。
rabbitmq要求集羣中至少一個磁盤節點【爲了提升性能,不須要所有節點都是disc的節點】,因此咱們能夠啓動部分節點爲RAM模式
當節點加入或者離開集羣時,他們必須通知到至少一個磁盤節點。
若是集羣內就1個磁盤節點,其他都是內存節點。若是這個惟一的一個磁盤節點宕機了,那麼集羣仍是能夠路由消息的。可是這個時候不支持以下操做:
建立隊列、建立交換器、建立綁定、添加用戶、更改權限、添加或刪除集羣節點
以node72、node73爲例。
step1、將node72 、node73從集羣中移除
在node72上執行:
rabbitmqctl stop_app
rabbitmqctl reset
而後,執行下面命令,將節點再次加回集羣中:
rabbitmqctl join_cluster --ram rabbit@node1 // 說明:咱們也能夠在一開始搭建集羣的時候,就用 --ram參數添加節點
rabbitmqctl start_app
再次查看集羣狀態,以下圖:
可使用Haproxy、Nginx作4層負載均衡,若是使用的是阿里雲環境 還能夠直接使用使用阿里雲的SLB服務。
配置文件: /etc/rabbitmq/rabbitmq.config
部分參數:
{vm_memory_high_watermark, 0.4} 控制rabbitmq容許消耗的內存佔宿主機內存的的百分比。
{msg_store_file_size_limit, 16777216} 控制rabbitmq垃圾收集存儲內容以前,消息存儲數據庫的最大大小。默認16MB
{queue_index_max_journal_entries, 32768} 在轉儲到消息存儲數據庫並提交前,消息存儲日誌中的最大條目數,默認32768條
具體的運行參數還有不少,官方文檔都有很詳細的說明,其實咱們通常要改的參數也很少。
例子:
[root@node1 /root ]# rabbitmqctl add_user ops 123456 -- 添加一個普通帳號ops
[root@node1 /root ]# rabbitmqctl add_vhost vhost1 -- 添加一個虛擬主機vhost1
[root@node1 /root ]# rabbitmqctl set_permissions -p vhost1 ops ".*" ".*" ".*" -- 給ops帳戶的vhost1虛擬主機受權:配置、寫、讀 的權限。.*表示匹配任意隊列和交換器
[root@node1 /root ]# rabbitmqctl list_permissions -p vhost1 -- 列出vhost1當前開放的權限:
Listing permissions for vhost "vhost1" ...
ops .* .* .*
[root@node1 /root ]# rabbitmqctl set_permissions -p vhost2 ops "coupons-queue-.*" ".*" ".*"
[root@node1 /root ]# rabbitmqctl list_permissions -p vhost2
Listing permissions for vhost "vhost2" ...
ops coupons-queue-.* .* all
在rabbitmq的web控制檯,看到的ops帳戶的權限以下:
[root@node1 /root ]# rabbitmqctl clear_permissions -p vhost1 ops -- 刪除vhost1虛擬主機上ops帳號的權限
[root@node1 /root ]# rabbitmqctl clear_permissions -p vhost2 ops -- 刪除vhost2虛擬主機上ops帳號的權限
說明:下面的命令實驗的結果,是由於我在rabbitmq的web界面執行了一些入隊、bind等系列操做後的結果
列出vhost1虛擬主機的所有隊列狀況(name、messages、consumers、memory狀況)
[root@node1 /root ]# rabbitmqctl list_queues -p vhost1 name messages consumers memory
Timeout: 60.0 seconds ...
Listing queues for vhost vhost1 ...
msg-inbox-errors 7 0 55760
檢查vhost1虛擬主機的隊列屬性
[root@node1 /root ]# rabbitmqctl list_queues -p vhost1 name durable auto_delete
Timeout: 60.0 seconds ...
Listing queues for vhost vhost1 ...
msg-inbox-errors true false -- 能夠看出隊列是持久化的,未設置自動刪除
查看交換器和綁定狀況
[root@node1 /root ]# rabbitmqctl list_exchanges -p vhost1
Listing exchanges for vhost vhost1 ...
amq.topic topic
amq.headers headers
amq.match headers
amq.direct direct
amq.rabbitmq.trace topic
amq.fanout fanout
direct
查看rabbitmq默認交換器的屬性設置
[root@node1 /root ]# rabbitmqctl list_exchanges name type durable auto_delete
Listing exchanges for vhost / ...
amq.fanout fanout true false
direct true false
amq.rabbitmq.trace topic true false
amq.rabbitmq.log topic true false
amq.topic topic true false
amq.headers headers true false
amq.direct direct true false
amq.match headers true false
查看綁定信息
[root@node1 /root ]# rabbitmqctl list_bindings -p vhost1
Listing bindings for vhost vhost1...
exchange msg-inbox-errors queue msg-inbox-errors []
exchange q1 queue q1 []
amq.fanout exchange q1 queue []
test_change exchange msg-inbox-errors queue []
## 上面的q1、msg-inbox-errors隊列是我在rabbitmq管理界面手動綁定的。test_change是我人工建立的一個交換器
顯示broker的狀態
rabbitmqctl environment
查看rabbitmq的運行詳情(結果特別細緻)
rabbitmqctl status
列出consumer
list_consumers
列出channel
list_channels
列出鏈接信息
list_connections
默認日誌文件的路徑是 /var/log/rabbitmq/
rabbitmq的啓動日誌相似下圖這樣:
此外,這個文件還記錄了執行了哪些的管理操做,鏈接創建及斷開等不少運行狀態狀況。
切割日誌命令:
rabbitmqctl rotate_logs
rabbitmqctl reset命令:
reset 命令在節點爲單機狀態和是集羣的一部分時行爲有點不太同樣。
節點單機狀態時,reset 命令將清空節點的狀態,並將其恢復到空白狀態。當節點是集羣的一部分時,該命令也會和集羣中的磁盤節點通訊,告訴他們該節點正在離開集羣。
這很重要,否則,集羣會認爲該節點出了故障,並指望其最終可以恢復回來,在該節點回來以前,集羣禁止新的節點加入。
官方文檔:http://www.rabbitmq.com/heartbeats.html
https://www.cnblogs.com/Tommy-Yu/p/5775852.html
http://blog.csdn.net/jiao_fuyou/article/details/23186407
http://www.linuxidc.com/Linux/2014-01/95715.htm
心跳案例:http://holys.im/2016/09/20/why-rabbitmq-message-not-consumed/
心跳超時間隔
The heartbeat timeout value defines after what period of time the peer TCP connection should be considered dead by RabbitMQ and client libraries. This value is negotiated between the client and RabbitMQ server at the time of connection. The client must be configured to request heartbeats. In RabbitMQ versions 3.0 and higher, the broker will attempt to negotiate heartbeats by default (although the client can still veto them). The timeout is in seconds, and default value is 60 (580 prior to release 3.5.5).
心跳超時值決定了tcp相互鏈接的最大時間, 超過了這個時間, 該鏈接即被RMQ和客戶端視爲丟失(dead)。 這個值在客戶端和服務器創建鏈接的時候協商肯定。客戶端需配才能發心跳包。 RMQ3.0及以上版本, RMQ將試着將beatheart協調爲默認值(客戶端能夠否決這個值)。 超時時間單位爲秒,默認值爲60( 3.5.5發佈版以前是580)。
Heartbeat frames are sent about every timeout / 2 seconds. After two missed heartbeats, the peer is considered to be unreachable. Different clients manifest this differently but the TCP connection will be closed. When a client detects that RabbitMQ node is unreachable due to a heartbeat, it needs to re-connect.
心跳包每半個超時時間發送一次。 丟失了兩個心跳包, 鏈接被認爲不可抵達。 不一樣的客戶端有不一樣的提示, 但tcp鏈接都會被關閉。 當客戶端檢測到RMQ節點不可抵達(根據心跳斷定), 它須要從新鏈接(到服務器)。
Heartbeats can be disabled by setting the timeout interval to 0. This is not a recommended practice.
心跳機制能夠被禁用:設定超時間隔爲0。可是不建議這樣設置。
級聯複製:rabbitmq_shovel插件(用在跨IDC間的複製,通常狀況下,用的不多)
安裝方法:
rabbitmq-plugins enable rabbitmq_shovel
rabbitmq-plugins enable rabbitmq_shovel_management
官方介紹很詳細。這裏略過。
官方文檔:http://www.rabbitmq.com/management-cli.html
wget https://raw.githubusercontent.com/rabbitmq/rabbitmq-management/v3.7.2/bin/rabbitmqadmin
chmod +x rabbitmqadmin
mv rabbitmqadmin /usr/local/bin
rabbitmqadmin --help
rabbitmqadmin -V "/" list queues
rabbitmqadmin -V "/" list exchanges
在默認的vhost / 下面 建立一個名爲cli_test的exchange
rabbitmqadmin -V "/" -u guest -p guest declare exchange name=cli_test type=topic
列出鏈接列表
rabbitmqadmin list connections names
關閉消費者
rabbitmqadmin close connection name="127.0.0.1:11111"
1、使用 zabbix監控。
2、prometheus的監控的配置部署稍有複雜(須要在rabbitmq上額外的安裝plugin)。
3、使用rabbitmq自帶的REST API來採集監控(監控配置項的正確性,如是否配置了持久化、是否配置了鏡像隊列)