線上環(huán)境大規(guī)模RocketMQ集群不停機(jī)優(yōu)雅升級實(shí)踐
本文轉(zhuǎn)載自微信公眾號「 中間件興趣圈」,作者丁威 。轉(zhuǎn)載本文請聯(lián)系 中間件興趣圈公眾號。
RocketMQ集群的升級方案、落地實(shí)施就自然而然的落到了我的頭上,本文不僅要介紹一下筆者是如何升級的,更想展示作為一名架構(gòu)師,處理這些問題的方法論,展示大廠架構(gòu)師的工作日常。
溫馨提示:關(guān)于ACL相關(guān)的內(nèi)容,后續(xù)文章會單獨(dú)分享從4.1.0版本升級到4.8并開啟ACL的曲折經(jīng)歷。
1、版本升級的迫切性
說來慚愧,作為RocketMQ社區(qū)優(yōu)秀布道師,筆者所在公司的RocketMQ服務(wù)端版本竟然還是4.1.0,RocketMQ在4.4.0版本之前是不支持ACL(訪問控制),對應(yīng)生產(chǎn)環(huán)境中任意一臺機(jī)器都可以訂閱任意topic,在任意一臺生產(chǎn)應(yīng)用服務(wù)器都可以安裝一個(gè)rocketmq-console,從而控制整個(gè)集群,擁有刪除主題、刪除消費(fèi)組的權(quán)限,想想是不是后背發(fā)涼.
2、升級方案
2.1 確定升級到的版本
翻開RocketMQ升級日志,RocketMQ在4.4.0版本正式引入了ACL機(jī)制,故版本至少要升級到4.4.0,在業(yè)界使用開源版本有一個(gè)不成文的規(guī)則:通常不要使用最新的版本,不要充當(dāng)小白鼠。
但RocketMQ可以算是一個(gè)特殊。
通過仔細(xì)瀏覽RocketMQ的版本變更記錄,我們不難發(fā)現(xiàn)RocketMQ Client 相關(guān)的變更非常少,即與用戶關(guān)系緊密的消息發(fā)送、消息消費(fèi)這塊的代碼非常的穩(wěn)定,理論上基本不存在兼容性問題。并且每一個(gè)版本都修復(fù)了一些重大的BUG,性能提升也比較明顯,故筆者這次決定“冒天下之大不韙”,決定將幫升級到最新版本4.8.0。
在這里在啰嗦一些,簡單介紹一下RocketMQ幾個(gè)具有里程杯意義的版本。
- RocketMQ4.3.0正式引入了事務(wù)消息,如果大家希望使用事務(wù)消息,其版本最低建議為 4.6.1。
- RocketMQ4.4.0引入了ACL、消息軌跡,如果需要使用這些功能,其版本最低建議為 4.7.0。
- RocketMQ4.5.0引入了多副本(主從切換),其版本建議使用4.7.0。
- RocketMQ4.6.0引入了請求-響應(yīng)模型。
2.2 升級思路
版本升級的基本要求:業(yè)務(wù)不能停機(jī),即要做到對業(yè)務(wù)無感知的升級。
如果機(jī)器足夠的備用機(jī)器,最佳的版本遷移方案應(yīng)該是先擴(kuò)容再縮容,其示例圖如下:
其主要的思路是先對Broker進(jìn)行擴(kuò)容,加入兩臺高版本的Broker服務(wù)器,加入到集群中,然后關(guān)閉低版本Broker的寫權(quán)限,待消息過期后,將低版本移除,最后升級NameServer,完成不停機(jī)的在線遷移。
由于此次升級需要在半個(gè)月左右的時(shí)間內(nèi)將RocketMQ集群所有的節(jié)點(diǎn)全部升級,無法提供這么多冷備節(jié)點(diǎn),故先擴(kuò)容、再縮容無法滿足本次需求,本次只能基于已有的機(jī)器進(jìn)行升級。
能否直接升級Broker端代碼,但高版本的Broker直接使用低版本的Broker存儲目錄,即直接升級軟件,其示例圖如下:
核心思想是先停止老版本的Broker,然后使用新版本啟動Broker,但使用舊的配置文件。
有了思路,接下來就是要驗(yàn)證方案的可行性。
2.3 方案驗(yàn)證
理論歸理論,在生產(chǎn)環(huán)境做任何變更之前,必須有充分的測試驗(yàn)證,版本升級重點(diǎn)需要驗(yàn)證兼容性問題。
2.2.1 服務(wù)端版本兼容性驗(yàn)證
搭建一個(gè)上述MQ集群,其核心要點(diǎn):
- 高版本的Broker是否能向低版本的NameServer注冊路由
- 低版本的Broker是否能向高版本的NameServer注冊路由
通過rocketmq-console,去創(chuàng)建多個(gè)個(gè)topic,看看其路由信息是否正確,經(jīng)驗(yàn)證,符合預(yù)期。
2.2.2 客戶端與服務(wù)端兼容性驗(yàn)證
RocketMQ的客戶端API其實(shí)比較單一,無非就是消息發(fā)送、批量發(fā)送,消息消費(fèi),由于4.1版本不支持事務(wù)消息,這次升級甚至都無需驗(yàn)證事務(wù)消息,驗(yàn)證的要點(diǎn):
- 低版本的客戶端是否能正常向高版本Broker發(fā)送消息,消費(fèi)消息
- 高版本的客戶端是否能向低版本的Broker發(fā)送消息,消費(fèi)消息
測試案例來自哪,其實(shí)都不需要我們自己寫,直接用官方的Demo即可,其代碼截圖如下:
客戶端驗(yàn)證在真正實(shí)施過程中,其實(shí)比服務(wù)端之間的驗(yàn)證要復(fù)雜的多,由于各個(gè)項(xiàng)目組使用的客戶端版本不一,甚至有些項(xiàng)目組會使用c++、Python等其他非Java客戶端,如何精確找到該集群中所有客戶端的連接信息(客戶端版本、語言類型)至關(guān)重要。
官方提供的版本,對消費(fèi)組的連接信息還是支持的比較友好,我們可以通過寫腳本,先查詢系統(tǒng)中所有的消費(fèi)組,然后遍歷每一個(gè)消費(fèi)組,可以查詢這些消費(fèi)組的IP地址、客戶端版本、使用的語言等信息,但開源版本對生產(chǎn)者支持的不友好,沒有一個(gè)可獲取所有發(fā)送者相關(guān)的接口。
獲取消費(fèi)組消費(fèi)端的連接方式如下圖所示:
故我們采取的方式,主要是基于消費(fèi)組失敗客戶端類型,本次升級過程中,我也對RocketMQ做了一些定制化開發(fā),可方便獲取所有發(fā)送方的鏈接信息,后續(xù)會已提交PR的方式貢獻(xiàn)給官方。
2.2.3 Broker端存儲格式驗(yàn)證
由于沒有空閑資源,本次要使用的升級方式是直接升級軟件,但新老版本共用存儲目錄,基于RocketMQ的消息存儲協(xié)議,從4.0.0版本之后就一直沒有變化,其驗(yàn)證的關(guān)鍵點(diǎn)如下:
- 4.8.0版本是否可以直接使用4.1.0生成的存儲文件(commitlog等文件)
- 4.1.0版本是否可以直接使用4.8.0生成的存儲文件
為什么需要驗(yàn)證4.1.0版本能兼容4.8.0呢?因?yàn)槿绻壥。枰貪L,如果4.1.0版本不能兼容4.8.0的話,會讓你沒有退路,這在架構(gòu)設(shè)計(jì)中是絕對不允許的。
經(jīng)過驗(yàn)證發(fā)現(xiàn),存儲文件是相互兼容的。
2.2.4 測試環(huán)境驗(yàn)證
經(jīng)過上面三步的驗(yàn)證,已經(jīng)可以進(jìn)行升級了,但升級之前,還要在測試環(huán)境穩(wěn)定運(yùn)行一天,可以將測試環(huán)境升級成如下架構(gòu):
即不同版本的混搭模式,接受測試環(huán)境所有應(yīng)用服務(wù)器的驗(yàn)證,如果測試環(huán)境運(yùn)行沒有問題,即可在生產(chǎn)環(huán)境進(jìn)行升級。
2.4 實(shí)施方案
有了上面升級方案,并且已經(jīng)做了充分的驗(yàn)證,是可以在生產(chǎn)環(huán)境執(zhí)行了,在執(zhí)行之前,需要對理論設(shè)計(jì)輸出可執(zhí)行可落地的實(shí)施方案,實(shí)施方案必須要包括回滾操作,并且這個(gè)回滾操作一定要比較容易執(zhí)行,否則你的方案一定是不那么可靠的。
接下來重點(diǎn)闡述一下實(shí)施過程中一些關(guān)鍵步驟,整個(gè)升級步驟才有滾動升級,即逐臺升級。
1、關(guān)閉一個(gè)Broker的寫權(quán)限
關(guān)閉Broker寫權(quán)限,讓應(yīng)用將流量平滑遷移到其他節(jié)點(diǎn),這樣可以有效避免在對該機(jī)器進(jìn)行重啟時(shí)對業(yè)務(wù)造成的影響。
- sh ./mqadmin updateBrokerConfig -b 192.168.x.x:10911 -n 192.168.xx.xx:9876 -k brokerPermission -v 4
2、帶Broker寫入、消費(fèi)tps接近0時(shí),關(guān)閉broker
- ps -ef | grep java
- kill pid
3、使用新版本啟動Broker
注意,此過程使用的配置文件為老版本的配置,故此時(shí)并沒有開啟寫權(quán)限,啟動并不會對客戶端消息寫入造成影響。
4、開啟寫權(quán)限
待新版本啟動成功后,既可以開啟寫權(quán)限
- sh ./mqadmin updateBrokerConfig -b 192.168.xx.xx:10911 -n 192.168.xx.xx:9876 -k brokerPermission -v 6
觀察流量。
重復(fù)上述步驟即可完成Broker的升級。
關(guān)于Nameserver的升級就更加容易了,采用滾動升級,kill掉老版本的nameserver,在原機(jī)器上啟動新版本的nameserver即可。