4 單機集羣(跟多主機集羣相似)node
首先過一下rabbitmqctl提供的方法git
$sudo rabbitmqctl | egrep cluster join_cluster <clusternode> [--ram] 加入集羣,cluster方法的升級,更加簡單 cluster_status 查看集羣狀態,app不啓動,也是能夠查看基本信息 change_cluster_node_type disc | ram 更改節點類型 forget_cluster_node [--offline] 移除集羣 rename_cluster_node oldnode1 newnode1 [oldnode2] [newnode2 ...] 重命名節點名稱 update_cluster_nodes clusternode 更新節點 set_cluster_name name 設置集羣名稱
0 若是已經啓動management插件,則先要關閉插件github
sudo rabbitmq-plugins disable rabbitmq_management
1 啓動多個rabbitmq實例docker
sudo RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit rabbitmq-server -detatched & sudo RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=rabbit_1 rabbitmq-server -detatched & sudo RABBITMQ_NODE_PORT=5674 RABBITMQ_NODENAME=rabbit_2 rabbitmq-server -detatched &
啓動成功輸出:bash
... completed with 0 plugins. completed with 0 plugins. completed with 0 plugins. ...
查看3個進程是否啓動服務器
sudo netstat -pan |egrep "5672|5673|5674"
或者markdown
sudo rabbitmqctl -n rabbit@zhaofeng-pc status ;\ sudo rabbitmqctl -n rabbit_1@zhaofeng-pc status ;\ sudo rabbitmqctl -n rabbit_2@zhaofeng-pc status
2 加入集羣 rabbitmq集羣依賴的是erlang opt功能 rabbitmq的集羣按節點持久化類型分爲磁盤型和內存型,磁盤型節點必須有一個;按照性質可分爲持有者和複製者.cookie
如今將rabbit和rabbit_1,以磁盤的類型接入集羣,加入集羣時,能夠將一個節點當作全部者節點, 其餘節點依次接入到全部者集羣.網絡
接入集羣的三個步驟,stop_app,join_cluster,start_app 首先查看集羣狀態app
sudo rabbitmqctl -n rabbit@zhaofeng-pc cluster_status ;\ sudo rabbitmqctl -n rabbit_1@zhaofeng-pc cluster_status ;\ sudo rabbitmqctl -n rabbit_2@zhaofeng-pc cluster_status
能夠看到集羣都是單節點的.如今把rabbit和rabbit_1加到同一個集羣,上面已經看到了,每一個節點 其實都是在集羣中,只不過只有他們自己節點,那麼,如今就只須要將rabbit_1加到rabbit便可.
sudo rabbitmqctl -n rabbit_1@zhaofeng-pc stop_app sudo rabbitmqctl -n rabbit_1@zhaofeng-pc join_cluster rabbit@zhaofeng-pc sudo rabbitmqctl -n rabbit_1@zhaofeng-pc start_app
下面咱們將rabbit_2以ram類型加入rabbit
sudo rabbitmqctl -n rabbit_2@zhaofeng-pc stop_app sudo rabbitmqctl -n rabbit_2@zhaofeng-pc join_cluster --ram rabbit@zhaofeng-pc sudo rabbitmqctl -n rabbit_2@zhaofeng-pc start_app
操做到如今,你應該能夠看到相似下面信息
Cluster status of node 'rabbit_2@zhaofeng-pc' [{nodes,[{disc,['rabbit_1@zhaofeng-pc','rabbit@zhaofeng-pc']}, {ram,['rabbit_2@zhaofeng-pc']}]}, {running_nodes,['rabbit@zhaofeng-pc','rabbit_1@zhaofeng-pc', 'rabbit_2@zhaofeng-pc']}, {cluster_name,<<"rabbit@zhaofeng-pc">>}, {partitions,[]}, {alarms,[{'rabbit@zhaofeng-pc',[]}, {'rabbit_1@zhaofeng-pc',[]}, {'rabbit_2@zhaofeng-pc',[]}]}]
3 集羣客戶端代碼驗證
如今開始進行代碼驗證,是否真正的集羣了 測試代碼跟官方hello world同樣簡單,不在這裏粘貼.
集羣中有3個服務器(本地),向任意一個服務中發送消息,都可以在其餘服務器接收到消息, 證實集羣有效
4 集羣節點其餘操做
爲了提升性能,如今咱們改變一下rabbit_1的類型爲ram
sudo rabbitmqctl -n rabbit_1@zhaofeng-pc stop_app sudo rabbitmqctl -n rabbit_1@zhaofeng-pc change_cluster_node_type ram sudo rabbitmqctl -n rabbit_1@zhaofeng-pc start_app
如今你能夠看到rabbit_1已經變成了ram類型的節點了. 若是發現節點有問題,或者其餘緣由,想要下線集羣,能夠經過reset/force_reset或forget_cluster_node, 其中,reset:重置自己的節點,必須等待stop_app; forget_cluster_node:集羣中在線的節點,將已下線的節點移除集羣,用於刪除故障節點
$sudo rabbitmqctl -n rabbit_2@zhaofeng-pc reset Resetting node 'rabbit_2@zhaofeng-pc' Error: Mnesia is still running on node 'rabbit_2@zhaofeng-pc'. Please stop the node with rabbitmqctl stop_app first. sudo rabbitmqctl -n rabbit_2@zhaofeng-pc stop_app sudo rabbitmqctl -n rabbit_2@zhaofeng-pc reset sudo rabbitmqctl -n rabbit_2@zhaofeng-pc start_app
使用 forget_cluster_node,其中--offline,用於刪除最後一個節點
sudo rabbitmqctl -n rabbit_2@zhaofeng-pc stop_app sudo rabbitmqctl -n rabbit@zhaofeng-pc forget_cluster_node rabbit_2@zhaofeng-pc
處理完了,從新上線
sudo rabbitmqctl -n rabbit_2@zhaofeng-pc join_cluster rabbit@zhaofeng-pc sudo rabbitmqctl -n rabbit_2@zhaofeng-pc start_app
其餘的小功能: 集羣任意節點重命名集羣名稱,默認集羣名稱爲收割加入節點的節點名稱 默認是:
$sudo rabbitmqctl -n rabbit_2@zhaofeng-pc cluster_status {cluster_name,<<"rabbit@zhaofeng-pc">>}, $sudo rabbitmqctl -n rabbit_2@zhaofeng-pc set_cluster_name rabbit-cluster Setting cluster name to rabbit-cluster $sudo rabbitmqctl -n rabbit_2@zhaofeng-pc cluster_status ... {cluster_name,<<"rabbit-cluster">>}, ...
5 多機器(真機)集羣
第一點 注意erlang-cookie要保持一致. cookie 存放的位置在:
sudo cat ~/.erlang.cookie sudo cat /var/lib/rabbitmq/.erlang.cookie
第二點 rabbitmq的版本要一致
咱們可使用docker 驗證一下
啓動3個容器
docker run --rm -d --hostname my-rabbit --name my-rabbit -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq docker run --rm -d --hostname my-rabbit-1 --name my-rabbit-1 -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq docker run --rm -d --hostname my-rabbit-2 --name my-rabbit-2 -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq
查看第一個IP,其後兩個ip依次累加
$docker inspect my-rabbit | grep IPAddress "SecondaryIPAddresses": null, "IPAddress": "172.17.0.3", "IPAddress": "172.17.0.3",
如今已經知道三個機器地址了.用到本文講得,依次爲三個服務器添加遠程用戶
$docker exec -it my-rabbit bash root@my-rabbit:/# rabbitmqctl add_user admin admin Creating user "admin" root@my-rabbit:/# rabbitmqctl authenticate_user admin admin Authenticating user "admin" Success root@my-rabbit:/# rabbitmqctl set_permissions -p / admin '.*' '.*' '.*' Setting permissions for user "admin" in vhost "/" root@my-rabbit:/# rabbitmqctl list_user_permissions admin Listing permissions for user "admin" / .* .* .*
rabbitmq依賴的是主機名,因此還要在/etc/hosts
添加其餘節點主機信息, 事實上,只要保證非全部者節點有全部者節點便可
172.17.0.3 my-rabbit root@my-rabbit:/# echo -e "172.17.0.3 my-rabbit\n172.17.0.4 my-rabbit-1\n172.17.0.5 my-rabbit-2" >> /etc/hosts
或者是,使用--link,直接使用其餘容器
添加完了這些,剩下的就是stop_app,join_cluster,start_app了,下面舉例一個
root@my-rabbit-1:/# rabbitmqctl stop_app Stopping rabbit application on node 'rabbit@my-rabbit-1' root@my-rabbit-1:/# rabbitmqctl join_cluster --ram rabbit@my-rabbit Clustering node 'rabbit@my-rabbit-1' with 'rabbit@my-rabbit' root@my-rabbit-1:/# rabbitmqctl start_app Starting node 'rabbit@my-rabbit-1' root@my-rabbit-1:/# rabbitmqctl cluster_status Cluster status of node 'rabbit@my-rabbit-1' [{nodes,[{disc,['rabbit@my-rabbit-2','rabbit@my-rabbit']}, {ram,['rabbit@my-rabbit-1']}]}, {running_nodes,['rabbit@my-rabbit','rabbit@my-rabbit-2', 'rabbit@my-rabbit-1']}, {cluster_name,<<"rabbit@my-rabbit">>}, {partitions,[]}, {alarms,[{'rabbit@my-rabbit',[]}, {'rabbit@my-rabbit-2',[]}, {'rabbit@my-rabbit-1',[]}]}]
如今咱們已經實現了真機(測試/生產環境)條件下的集羣了. 我使用docker,建立了簡單的集羣鏡像,方便測試使用
代碼測試正常! 測試代碼鏈接
6 其餘的分佈式方式
官方還提供了一種Federation / Shovel的方式,這是一種轉發的機制,消息能夠發我其餘的服務節點.
這二者的區別
分佈式原理: Federation / Shovel: exchange 邏輯上是分離的,可能有不一樣的擁有者
Federation/Shovel | cluster |
---|---|
exchange是邏輯分離的,可能有不一樣擁有者 | 單個邏輯exchange |
不限制rabbitmq和erlang 版本 | rabbitmq和erlang 版本要保持一致 |
exchange能夠經過不可靠(公網)網絡鏈接,<br/>直接使用amqp鏈接,可是須要設置用戶權限. | 可靠(內網)網絡,通訊依賴Erlang interode,共享erlang cookie |
拓撲結構能夠是單項或雙向 | 節點兩兩互聯 |
cap理論中的ap | cap理論中的cp |
exchange能夠有單獨的信息,有些消息是本地的 | 每一個節點的消息都是相同的 |
客戶端只能看到鏈接的服務器隊列 | 客戶端能夠看到集羣內全部隊列 |
因爲我的水平有限,若有問題請指出。