# RabbitMQ 叢集搭建 ###### tags: `技術備忘錄` `RabbitMQ` 安裝篇->[RabbitMQ 快速安裝筆記](/DZaDoKJ8REit9tTgE_3v2Q) 入門篇->[RabbitMQ 筆記](/6X7MdpOfTEOuSFrLG0SdhQ) --- [TOC] --- ## 相關連結 [官方Clustering Guide](https://www.rabbitmq.com/clustering.html) [Rabbitmq叢集搭建-程式前沿](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/395960/) ## 基本設定步驟 #### vi /etc/hosts 對應設定 ```bash ip hostname ``` > **好像**需要把現有的 Nodes 全部新增上去,不然在join時會出錯。 #### 啟動叢集(每台主機) ```bash=1 rabbitmqctl stop rabbitmq-server -detached rabbitmqctl start_app ``` #### 叢集串接 ```bash=4 rabbitmqctl stop_app rabbitmqctl reset #disk模式 rabbitmqctl join_cluster rabbit@hostname #RAM模式 #rabbitmqctl join_cluster --ram rabbit@hostname rabbitmqctl start_app ``` ## Quorum Queues ***A.K.A. HA Queues*** [官方文件](https://www.rabbitmq.com/quorum-queues.html) 在cluster多節點(Nodes)的情形下才可以新增的Queue格式 ![](https://i.imgur.com/21u4JFX.png) 新增時會需要先綁在其中一個Node上 如果原先綁定的Node離線,會自動將資料導到另一個Node上 ![](https://i.imgur.com/b26fvPo.png) > 旁邊的"+"代表這個Queue現在有對應到的Node數 :::warning Quorum Queues 對應的 Node 只會包含 Queue 建立的當下有的 Node 換言之 Queue 建好後,之後再加入的 Node 就無法對應到 ::: :::danger 如果啟動中的 Node 小於 3 台 Quorum Queues 會因為 Node 過少而出錯誤 ![](https://i.imgur.com/I8L7LzR.png) 所以說***啟動中 Node 必須要大於 3 台*** > 不過這個錯誤並不會導致Queue裡的資料消失 > 特殊情況: 如果 Node 為 "?",新的資料將**無法**寫進 Queue 中 ::: ## 實作 ### 連線 因為叢集多主機的特性,連線建立的時候如果將 HostName 寫在一般的 ConnectionFactory 裡,連線主機離線時,將無法自動重連。 如下改成 HostName List 後,即使任意節點斷線也不會影響連線。( **會自動斷線重連** ) ```csharp=1 string[] hostList = { "HostName1","HostName2","HostName3","HostName4" }; var connection = factory.CreateConnection(hostList) ``` 另外可以藉由這兩個 Event 監聽連線狀態 ```csharp //斷線後重新連線成功 connection.RecoverySucceeded //斷線 connection.ConnectionShutdown ``` ### 建立 Quorum Queues ```csharp channel.QueueDeclare( queue: "QueueName", durable: true, exclusive: false, autoDelete: false, arguments: new Dictionary<string, object>() { { "x-queue-type", "quorum" } } ); ``` 如上, durable、exclusive、autoDelete 的值不可改 > BTW , QueueName 如果直接不帶( 給 **""** ),系統會自動產生 QueueName ## Consul擴展 [官方文件](https://www.rabbitmq.com/cluster-formation.html#peer-discovery-consul) [帶有CONSUL和VAULT的RABBITMQ集群](https://piotrminkowski.com/2018/12/27/rabbitmq-cluster-with-consul-and-vault/) ```bash rabbitmq-plugins --offline enable rabbitmq_peer_discovery_consul ``` 我的 **/etc/rabbitmq/rabbitmq.conf** ```bash loopback_users.guest = false listeners.tcp.default = 5672 hipe_compile = false management.listener.port = 15672 management.listener.ssl = false cluster_formation.peer_discovery_backend = rabbit_peer_discovery_consul cluster_formation.consul.host = 192.168.11.191 cluster_formation.consul.svc_addr_auto = true cluster_formation.consul.svc_addr_use_nodename = false cluster_formation.consul.port = 8500 cluster_formation.consul.scheme = http cluster_formation.consul.svc = rabbitmq ``` > 如果 /etc/rabbitmq 沒有 rabbitmq.conf,直接建一個就可以了 > ## Docker Iamge ## 注意事項 ### /etc/hosts設定問題 根據[Rabbitmq叢集搭建-程式前沿](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/395960/)步驟,在設定 **/etc/hosts** 參數時,參考內容: ```bash 192.168.127.139 basic-server 192.168.127.140 rabbitmq-m1 192.168.127.132 rabbitmq-m2 ``` 其中**basic-server**,**rabbitmq-m1**,**rabbitmq-m2**,為主機名稱 不是連線叢集時的**rabbit@basic-server** [參照錯誤](https://blog.csdn.net/yy4545/article/details/100523954) ### EPMD錯誤 如果上方/etc/hosts設定沒問題但出EPMD錯誤,執行 ```bash=1 export ERL_EPMD_PORT="4369" epmd -kill ``` [官方說明](https://www.rabbitmq.com/networking.html#epmd)