接安所有門的行政要求,生產環境上百臺RocketMQ機器必須在半個月內升級,必須支持ACL,規避安全風險。java
RocketMQ集羣的升級方案、落地實施就天然而然的落到了個人頭上,本文不只要介紹一下筆者是如何升級的,更想展現做爲一名架構師,處理這些問題的方法論,展現大廠架構師的工做平常。c++
>舒適提示:關於ACL相關的內容,後續文章會單獨分享從4.1.0版本升級到4.8並開啓ACL的曲折經歷。shell
一、版本升級的迫切性
說來慚愧,做爲RocketMQ社區優秀佈道師,筆者所在公司的RocketMQ服務端版本居然仍是4.1.0,RocketMQ在4.4.0版本以前是不支持ACL(訪問控制),對應生產環境中任意一臺機器均可以訂閱任意topic,在任意一臺生產應用服務器均可以安裝一個rocketmq-console,從而控制整個集羣,擁有刪除主題、刪除消費組的權限,想一想是否是後背發涼.安全
二、升級方案
2.1 肯定升級到的版本
翻開RocketMQ升級日誌,RocketMQ在4.4.0版本正式引入了ACL機制,故版本至少要升級到4.4.0,在業界使用開源版本有一個不成文的規則:一般不要使用最新的版本,不要充當小白鼠。服務器
但RocketMQ能夠算是一個特殊。微信
經過仔細瀏覽RocketMQ的版本變動記錄,咱們不難發現RocketMQ Client 相關的變動很是少,即與用戶關係緊密的消息發送、消息消費這塊的代碼很是的穩定,理論上基本不存在兼容性問題。而且每個版本都修復了一些重大的BUG,性能提高也比較明顯,故筆者此次決定「冒天下之大不韙」,決定將幫升級到最新版本4.8.0。架構
在這裏在囉嗦一些,簡單介紹一下RocketMQ幾個具備里程杯意義的版本。運維
- RocketMQ4.3.0正式引入了事務消息,若是你們但願使用事務消息,其版本最低建議爲 4.6.1。
- RocketMQ4.4.0引入了ACL、消息軌跡,若是須要使用這些功能,其版本最低建議爲 4.7.0。
- RocketMQ4.5.0引入了多副本(主從切換),其版本建議使用4.7.0。
- RocketMQ4.6.0引入了請求-響應模型。
2.2 升級思路
版本升級的基本要求:業務不能停機,即要作到對業務無感知的升級。性能
若是機器足夠的備用機器,最佳的版本遷移方案應該是先擴容再縮容,其示例圖以下: 其主要的思路是先對Broker進行擴容,加入兩臺高版本的Broker服務器,加入到集羣中,而後關閉低版本Broker的寫權限,待消息過時後,將低版本移除,最後升級NameServer,完成不停機的在線遷移。測試
因爲這次升級須要在半個月左右的時間內將RocketMQ集羣全部的節點所有升級,沒法提供這麼多冷備節點,故先擴容、再縮容沒法知足本次需求,本次只能基於已有的機器進行升級。
可否直接升級Broker端代碼,但高版本的Broker直接使用低版本的Broker存儲目錄,即直接升級軟件,其示例圖以下: 核心思想是先中止老版本的Broker,而後使用新版本啓動Broker,但使用舊的配置文件。
有了思路,接下來就是要驗證方案的可行性。
2.3 方案驗證
理論歸理論,在生產環境作任何變動以前,必須有充分的測試驗證,版本升級重點須要驗證兼容性問題。
2.2.1 服務端版本兼容性驗證
搭建一個上述MQ集羣,其核心要點:
- 高版本的Broker是否能向低版本的NameServer註冊路由
- 低版本的Broker是否能向高版本的NameServer註冊路由
經過rocketmq-console,去建立多個個topic,看看其路由信息是否正確,經驗證,符合預期。
2.2.2 客戶端與服務端兼容性驗證
RocketMQ的客戶端API其實比較單一,無非就是消息發送、批量發送,消息消費,因爲4.1版本不支持事務消息,此次升級甚至都無需驗證事務消息,驗證的要點:
- 低版本的客戶端是否能正常向高版本Broker發送消息,消費消息
- 高版本的客戶端是否能向低版本的Broker發送消息,消費消息
測試案例來自哪,其實都不須要咱們本身寫,直接用官方的Demo便可,其代碼截圖以下: 客戶端驗證在真正實施過程當中,其實比服務端之間的驗證要複雜的多,因爲各個項目組使用的客戶端版本不一,甚至有些項目組會使用c++、Python等其餘非Java客戶端,如何精確找到該集羣中全部客戶端的鏈接信息(客戶端版本、語言類型)相當重要。
官方提供的版本,對消費組的鏈接信息仍是支持的比較友好,咱們能夠經過寫腳本,先查詢系統中全部的消費組,而後遍歷每個消費組,能夠查詢這些消費組的IP地址、客戶端版本、使用的語言等信息,但開源版本對生產者支持的不友好,沒有一個可獲取全部發送者相關的接口。
獲取消費組消費端的鏈接方式以下圖所示: 故咱們採起的方式,主要是基於消費組失敗客戶端類型,本次升級過程當中,我也對RocketMQ作了一些定製化開發,可方便獲取全部發送方的連接信息,後續會已提交PR的方式貢獻給官方。
2.2.3 Broker端存儲格式驗證
因爲沒有空閒資源,本次要使用的升級方式是直接升級軟件,但新老版本共用存儲目錄,基於RocketMQ的消息存儲協議,從4.0.0版本以後就一直沒有變化,其驗證的關鍵點以下:
- 4.8.0版本是否能夠直接使用4.1.0生成的存儲文件(commitlog等文件)
- 4.1.0版本是否能夠直接使用4.8.0生成的存儲文件
爲何須要驗證4.1.0版本能兼容4.8.0呢?由於若是升級失敗,須要回滾,若是4.1.0版本不能兼容4.8.0的話,會讓你沒有退路,這在架構設計中是絕對不容許的。
通過驗證發現,存儲文件是相互兼容的。
2.2.4 測試環境驗證
通過上面三步的驗證,已經能夠進行升級了,但升級以前,還要在測試環境穩定運行一天,能夠將測試環境升級成以下架構: 即不一樣版本的混搭模式,接受測試環境全部應用服務器的驗證,若是測試環境運行沒有問題,便可在生產環境進行升級。
2.4 實施方案
有了上面升級方案,而且已經作了充分的驗證,是能夠在生產環境執行了,在執行以前,須要對理論設計輸出可執行可落地的實施方案,實施方案必需要包括回滾操做,而且這個回滾操做必定要比較容易執行,不然你的方案必定是不那麼可靠的。
接下來重點闡述一下實施過程當中一些關鍵步驟,整個升級步驟纔有滾動升級,即逐臺升級。
一、關閉一個Broker的寫權限
關閉Broker寫權限,讓應用將流量平滑遷移到其餘節點,這樣能夠有效避免在對該機器進行重啓時對業務形成的影響。
sh ./mqadmin updateBrokerConfig -b 192.168.x.x:10911 -n 192.168.xx.xx:9876 -k brokerPermission -v 4
二、帶Broker寫入、消費tps接近0時,關閉broker
ps -ef | grep java kill pid
三、使用新版本啓動Broker
注意,此過程使用的配置文件爲老版本的配置,故此時並無開啓寫權限,啓動並不會對客戶端消息寫入形成影響。
4、開啓寫權限
待新版本啓動成功後,既能夠開啓寫權限
sh ./mqadmin updateBrokerConfig -b 192.168.xx.xx:10911 -n 192.168.xx.xx:9876 -k brokerPermission -v 6
觀察流量。
重複上述步驟便可完成Broker的升級。
關於Nameserver的升級就更加容易了,採用滾動升級,kill掉老版本的nameserver,在原機器上啓動新版本的nameserver便可。
三、花絮
最後和你們再分享一個小小的插曲。儘管上面的方案很是詳細,而且通過反覆的測試,但MQ在咱們公司的重要性實在過重要,運維小夥伴在操做時不敢下手,在操做時他要我在身邊看着,這個時候,做爲架構師的咱們要勇於承擔責任,明確告知,只要你操做正確,出力故障由我來承擔,這也是我我的以爲做爲架構師一個很是重要的軟技能:對你負責的技術具備掌控力,而且勇於擔當。
好了,本文就介紹到這裏了,您的一鍵三連是對我最大的鼓勵,固然能夠加筆者微信:dingwpmz,備註CSDN,共同交流探討。
最後分享筆者一個硬核的RocketMQ電子書,您將得到千億級消息流轉的運維經驗。 獲取方式:微信搜索【中間件興趣圈】,回覆RMQPDF便可獲取。