作者 | Halimao Java、go 愛好者( https://github.com/halimao/

【Arthas 官方社區正在舉行徵文活動,參加即有獎品拿哦~ 點擊投稿

生產環境的 bug 開發環境無法復現怎麼辦?關鍵位置沒有打印日誌信息不足怎麼辦?莫慌,騷年。讓強大的 Arthas法師來 carry,帶你去生產環境"遨遊"闖關。

剛接觸 Arthas,就被它能夠 watch 方法的輸入參數和返回值的功能震驚到了。這簡直太酷炫了,讓你可以像本地單步調試一樣,跟蹤到每一步的執行結果和獲取當前的變量數值。以前要定位線上問題,信息不足就需要加日誌打印,定位問題,可能需要反覆重啓應用。用了 Arthas,根本不需要加日誌打印,重啓應用這些操作。花了大概一個週末下午,在本地跑了下官方 demo,熟悉了下常用操作。腦子裏對 Arthas 能夠做什麼,能解決什麼,怎麼解決,已經有了大概的瞭解。後面需要用的時候,就能派上大用場了(學了就一定有 bug 會找上門的=.=)。

下面介紹一個特意找上門的 bug。

背景:同一個聊天交友類產品,對外以一個主品牌以及多個新品牌進行發佈。服務端是共用一套數據的,但是所有對外展示的信息,涉及到品牌相關的,需要進行文案替換。在同一個羣組裏,主品牌和新品牌的用戶可以互相聊天。

問題現象:

  • 線上某個羣組裏面,同一條聊天消息涉及到需要替換文案的內容時,主品牌側的用戶有的顯示正常,有的顯示爲新品牌文案;
  • 不同的羣聊天消息,同一個用戶有的展示正常,有的異常;
  • 新品牌側的用戶看到的羣聊天消息文案替換正常。

先貼下相關的代碼(用 Arthas 的 jad 直接反編譯的源碼):

羣聊消息下發方法:

write 方法文案替換邏輯代碼:

PublishMessage 是下行消息類,replaceMsgMap 是提前生成好的各個新品牌對應文案,主品牌使用原始消息文案。

乍一看,文案替換邏輯沒啥毛病(但問題就在這,大家可以先思考下),感覺自己又要去面對一個撲朔迷離的玄學 bug 了(永遠不要把程序 bug 歸結爲靈異事件)。代碼看不出問題,本地單步調試鼓搗了一早上,也沒復現出來,看來只能在生產環境定位了,Arthas 要登場了。

由於生產環境的消息轉發量很大,直接 attach 進程風險太高,且不利於單條消息觀察定位。所以選擇預發佈環境進行 attach,請求量可控,數據和線上一致,也只有讀操作,不會影響到生產環境。

用 Arthas 的 watch 命令,觀察 write 方法的輸入參數。

  • -x 表示遍歷深度,可以調整來打印具體的參數和結果內容,默認值是 1
  • -b 表示觀察方法調用前

可以看到,publishMessage、userSession 參數的值都顯示出來了。接着就可以在預發佈觸發消息下行進行數據觀察了。

建了個測試羣,除了自己一個主品牌的測試用戶還有另外一個新品牌用戶。最初開始發送了幾條羣聊消息都正常,後面又拉了一個新品牌用戶以及主品牌測試用戶,復現的概率就高了許多。觀察了下同一條羣聊消息發給每個羣成員的 publishMessage 值,發現如果先遍歷到了新品牌用戶,再遍歷到主品牌用戶時,publishMessage 的文案居然是新品牌文案!!!心裏猛的一驚,是了,就是這個低級錯誤造成的 bug,大家應該也猜到原因了。

下面揭曉下這個問題產生的原因:

  • 遍歷羣成員傳遞的 publishMessage 形參,每次改變 payload 都會影響到被傳遞進去的 publishMessage 實參
  • replaceMsgMap 裏只存儲了新品牌文案
  • 主品牌根據 appName 獲取對應文案時爲空,則不設置 payload,使用最傳遞進來的 publishMessage 的 payload
  • 遍歷羣組成員時,順序是隨機性的

如果某個主品牌用戶在新品牌用戶之後被遍歷到,那麼 publishMessage 的 payload 字段就會被設置爲新品牌文案。而主品牌在 replaceMsgMap 裏找不到對應文案,就不更新 payload了,複用了上一次被遍歷用戶的 payload,就會出現文案顯示異常。

知道原因後就好處理了,replaceMsgMap 裏把主品牌的文案也加進去,每次遍歷到主品牌,也更新 payload 字段,保證文案正常顯示。

整個定位過程,無需增加 log 日誌,線上應用也無需重啓,便能獲取足夠的信息進行問題排查定位,是不是賊好用了。花個半天時間,摸索鼓搗下,要用時就能省下不少工夫。詳細使用文檔見-> 官方文檔

一鍵安裝並啓動 Arthas

  • 方式一:通過 Cloud Toolkit 實現 Arthas 一鍵遠程診斷

Cloud Toolkit 是阿里雲發佈的免費本地 IDE 插件,幫助開發者更高效地開發、測試、診斷並部署應用。通過插件,可以將本地應用一鍵部署到任意服務器,甚至雲端(ECS、EDAS、ACK、ACR 和 小程序雲等);並且還內置了 Arthas 診斷、Dubbo工具、Terminal 終端、文件上傳、函數計算 和 MySQL 執行器等工具。不僅僅有 IntelliJ IDEA 主流版本,還有 Eclipse、Pycharm、Maven 等其他版本。

推薦使用 IDEA 插件下載 Cloud Toolkit 來使用 Arthas: http://t.tb.cn/2A5CbHWveOXzI7sFakaCw8

  • 方式二:直接下載

地址: https://github.com/alibaba/arthas

Arthas 徵文活動火熱進行中

Arthas 官方正在舉行徵文活動,如果你有:

  • 使用 Arthas 排查過的問題
  • 對 Arthas 進行源碼解讀
  • 對 Arthas 提出建議
  • 不限,其它與 Arthas 有關的內容
    歡迎參加徵文活動,還有獎品拿哦~ 點擊投稿

阿里巴巴雲原生 關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公衆號。”

相關文章