全網最簡單的安裝手冊
// 安裝erlangwget https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.shbash script.rpm.shsudo yum install erlang// 安裝rabbitmq 3.7 版本wget https://antsentry-cloud-firmware.s3.cn-northwest-1.amazonaws.com.cn/raspberrypy/rabbitmq-server-3.7.26-1.el7.noarch.rpmsudo yum install rabbitmq-server-3.7.26-1.el7.noarch.rpmsudo service rabbitmq-server start
配置用戶
rabbitmqctl add_user username passwd // 添加用戶rabbitmqctl set_user_tags username administrator // 給用戶分配權限rabbitmqctl list_users // 查看系統中有哪些用戶
啟用web控制臺
sudo rabbitmq-plugins list // 查看啟用了哪些插件sudo rabbitmq-plugins enable rabbitmq_management // 啟用Web管理界面,默認埠是15672
經過上述幾個步驟,打開瀏覽器,輸入伺服器的ip和埠,就能看到久違的登錄界面了。
配置集群
至少需要兩個節點才能組成集群,簡單起見,就選兩臺啦。在另一臺服務上,重複上面的安裝過程,配置用戶和管理界面步驟可以略過。
複製前一臺伺服器上的cookie到新安裝的這臺伺服器,cookie所在目錄為:/var/lib/rabbitmq/.erlang.cookie。
Tips:如果copy,需要注意.erlang.cookie文件的權限必須是400。同時,不要用vim編輯器編輯,會留下換行符導致cookie不一致。cookie文件的大小為20位元組。上述兩個小問題,確實困擾了筆者挺長時間,導致安裝不成功。
sudo rabbitmqctl cluster_status // 查看集群狀態sudo rabbitmqctl stop_app // 停止appsudo rabbitmqctl join_cluster rabbit@ip-10-0-5-62 // 把當前節點添加到集群中sudo rabbitmqctl start_app // 啟動app
通過簡單的幾步,這兩臺伺服器已經組成集群了。登錄web控制臺,效果如下:
節點之間同步配置信息,關於集群的特點,這是最正確的描述。其他的一些特性,都是可配置的,例如內存節點、磁碟節點;鏡像模式等;持久化等等。在可用性和性能之間,用不同的配置,做相應的取捨。
代理中間件
在上一章節中介紹了集群的安裝,縱觀網上絕大多數的教程,到這裡並沒有結束,還有很重要的一步,那就是HAProxy+KeepAlived。筆者並沒有研究過HAProxy,更別提KeepAlive了,看到這樣的東東一臉懵逼。好在業務運行在雲上,雲服務上有TCP層的負載均衡(LB)組件,用LB代替HAProxy+KeepAlive是一樣的。結構如下:
從體系結構的角度考慮,集群中的節點是對等的,即客戶端連接任意一個節點都能正常工作,因為只有這樣,我們才能用粗暴的負載均衡器做代理。
從實現的細節看,也卻是如此。對生產者來說,發送給那個節點並不重要,路由到相應的queue master節點存儲即可。消費者若是連接到了master節點,直接取數據即可;如果連接到非master節點,創建一個master節點到目標節點的通道傳輸數據。
在軟體架構實踐中,這是非常普遍的一種模式,例如調用微服務的多個實例、例如訪問某個域名對應的多個IP位址,例如eureka註冊中心等,有些用了中心化的代理中間件,有些則是在客戶端實現的。同樣的道理,訪問rabbitmq集群,除了常見的代理中間件,也可採用客戶端代理實現。
客戶端代理
支持多個地址
通常,初始化ConnectionFactory只能接受一個地址。這麼看來,用官方SDK完成客戶端代理,要重寫基礎的訪問組件了,這條路肯定是沒有錯的,就像sharding-jdbc。仔細研究官方提供的API文檔,ConnnectionFactory有個newConnection函數,是可以傳入一個地址列表的,實現邏輯如下
factory.newConnection(addresses);
根據地址列表依次創建連接,直到創建成功為止。Tips:這段代碼並不優雅,如果直接用到這段代碼,會客戶端都連接到第一個正常的節點。
恢復連接
ConnectFactory個重要的功能,那就是自動恢復連接,代碼很簡單,在4.0版本以後是默認開啟的。按照官方的解釋,在連接失敗後,可以做到打開連接、恢復連接上的listeners、重新創建channel、恢復channel上的listeners以及配置信息。
factory.setAutomaticRecoveryEnabled(true);結合這兩個特性,經測試,集群中的節點宕機後,確實可以重新連接到另一個節點。但是,中間有一段時間連接是中斷的,生產者發送消息,會連續失敗!
補丁
為了解決這個問題,在生產者增加重試機制,問題得到解決。發送消息失敗後,要等待創建連接和channel,重新發送消息。
public void send(String exchange, MQMessage message) {try { sentMsg(exchange, message); } catch (Exception ex) { connnect(); }}
到此為止,驗證了通過客戶端代理模式訪問rabbitmq集群。但是,筆者在生產中真不敢這麼用。