公司一個 RocketMQ 集羣由4主4從組成,忽然其中3臺服務器「居然」在同一時間下線,其監控顯示以下: java
依次查看三臺機器的監控圖形,時間戳幾乎完美「吻合」,難以想象吧。出現問題,先二話不說,立刻重啓各服務器,儘快恢復集羣,下降對業務的影響,接下來開始對日誌進行分析。bash
Java 進程自動退出(rocketmq 自己就是一個java進程),一種最多見的問題是因爲內存溢出或因爲內存泄漏致使進程發送Crash等。因爲咱們的啓動參數中未配置-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/jvmdump 這兩個參數,不能直接根據 是否生成 dump 文件,那退而求其次去查看其GC日誌,將GC日誌下載到本地,而後可使用一個在線gc日誌分析工具:gceasy.io/ ,將 gc 日誌上傳後會給出圖形化的展現,其圖以下: 服務器
發現垃圾回收很正常。既然 Java 進程不是因爲內存溢出等問題致使的退出,那又會是什麼緣由呢?那咱們來看一下那個點的broker的日誌,其關鍵日誌截圖以下: 併發
發現 broker 日誌中有打印出 shutdownHook,表示在進程退出以前執行了啓動時註冊時的退出鉤子函數,說明 broker 是正常中止的,而且也不多是 kill -9 命令,確定是顯示的執行了 shutodown 或 kill 命令,因而立馬使用 history 命令 查看歷史命令,都未在指定時間執行過該命令,而且切換到 root 命令後,一樣使用 history 命令,並未發現端倪。但我始終相信,確定是執行了手動執行了 kill 命令致使進程退出的,通過網上查找查,得知能夠經過查閱系統日誌/var/log/messages 來查看系統命令的調用,因而乎把日誌文件下載到本地,開始搜索 kill 關鍵字,發現以下日誌: 運維
發現最近一次 kill 命令是在25號的凌晨1點多,中止 rocketmq 集羣,並使用 bin/mqbroker -c conf/broker-b.conf & 進行了從新啓動。這個命令是有問題的,沒有使用 nohup ,若是會話失效,該進程就會被退出,爲了驗證,咱們再查一下進程退出時的日誌: jvm
發如今故障發生點確實有 Removed 相關的日誌。故障緣由基本分析到位了,運維在啓動的時候沒有使用 nohup 來啓動,故立刻排查剛啓動的集羣的方式,從新重啓剛啓動的 Broker。函數
RocketMQ優雅重啓小建議:工具
首先將 broker 的寫權限關閉,命令以下:spa
bin/mqadmin updateBrokerConfig -b 192.168.x.x:10911 -n 192.168.x.x:9876 -k brokerPermission -v 4
複製代碼
經過 rocketmq-console 查看該broker的寫入TPS,當寫入TPS降爲0後,再使用 kill pid 關閉 rocketmq 進程。舒適提示:將broker的寫權限關閉後,非順序消息不會立馬拒絕,而是須要等客戶端路由信息更新後,不會在往該broker上發送消息,故這個過程須要等待。3d
啓動 rocketmq
nohup bin/mqbroker -c conf/broker-a.conf /dev/null 2>&1 &
複製代碼
注意:nohup。
恢復該節點的寫權限
bin/mqadmin updateBrokerConfig -b 192.168.x.x:10911 -n 192.168.x.x:9876 -k brokerPermission -v 6
複製代碼
本文的故障分析與處理就介紹到這裏,本文重點講解了故障的分析過程以及 RocketMQ Broker 優雅停機的方案。
若是本文對您有所幫助的話,麻煩幫忙點個贊,謝謝。
做者介紹:《RocketMQ技術內幕》做者,維護公衆號:中間件興趣圈,目前主要發表了源碼閱讀java集合、JUC(java併發包)、Netty、ElasticJob、Mycat、Dubbo、RocketMQ、mybaits等系列源碼。