1. 程式人生 > 實用技巧 >當Dubbo遇上Arthas,會碰撞出什麼樣的火花呢?

當Dubbo遇上Arthas,會碰撞出什麼樣的火花呢?

Apache Dubbo是Alibaba開源的高效能RPC框架,在國內有非常多的使用者。

  • Github:https://github.com/apache/incubator-dubbo
  • 文件:http://dubbo.incubator.apache.org/zh-cn/

Arthas是Alibaba開源的應用診斷利器,9月份開源以來,Github Star數三個月超過6000。

  • Github:https://github.com/alibaba/arthas
  • 文件:https://alibaba.github.io/arthas/

當Dubbo遇上Arthas,會碰撞出什麼樣的火花呢?下面來分享Arthas排查Dubbo問題的一些經驗。

dubbo-arthas-demo

下面的排查分享基於這個dubbo-arthas-demo,非常簡單的一個應用,瀏覽器請求從Spring MVC到Dubbo Client,再發送到Dubbo Server。

Demo裡有兩個spring boot應用,可以先啟動server-demo,再啟動client-demo。

  • https://github.com/hengyunabc/dubbo-arthas-demo
    在這裡插入圖片描述

Client端:
在這裡插入圖片描述

Server端:
在這裡插入圖片描述

Arthas快速開始

  • https://alibaba.github.io/arthas/install-detail.html
    在這裡插入圖片描述

啟動後,會列出所有的java程序,選擇1,然後回車,就會連線上ServerDemoApplication

在這裡插入圖片描述

Dubbo線上服務丟擲異常,怎麼獲取呼叫引數?

  • https://alibaba.github.io/arthas/watch.html

當線上服務丟擲異常時,最著急的是什麼引數導致了拋異常?

在demo裡,
訪問http://localhost:8080/user/0,UserServiceImpl就會丟擲一個異常,因為user id不合法。

在Arthas裡執行 watch com.example.UserService * -e -x 2 ‘{params,throwExp}’ ,然後再次訪問,就可以看到watch命令把引數和異常都打印出來了。

在這裡插入圖片描述

怎樣線上除錯Dubbo服務程式碼?

https://alibaba.github.io/arthas/redefine.html

在本地開發時,可能會用到熱部署工具,直接改程式碼,不需要重啟應用。但是在線上環境,有沒有辦法直接動態除錯程式碼?比如增加日誌。

在Arthas裡,可以通過redefine命令來達到線上不重啟,動態更新程式碼的效果。

比如我們修改下UserServiceImpl,用System.out打印出具體的User物件來:
在這裡插入圖片描述

本地編繹後,把
server-demo/target/classes/com/example/UserServiceImpl.class
傳到線上伺服器,然後用redefine命令來更新程式碼:

在這裡插入圖片描述

這樣子更新成功之後,訪問 http://localhost:8080/user/1,在ServerDemoApplication的控制檯裡就可以看到打印出了user資訊。

怎樣動態修改Dubbo的logger級別?

  • https://alibaba.github.io/arthas/ognl.html
  • https://alibaba.github.io/arthas/sc.html
  • https://commons.apache.org/proper/commons-ognl/language-guide.html

在排查問題時,需要檢視到更多的資訊,如果可以把logger級別修改為DEBUG,就非常有幫助。

ognl是apache開源的一個輕量級表示式引擎。下面通過Arthas裡的ognl命令來動態修改logger級別。

首先獲取Dubbo裡TraceFilter的一個logger物件,看下它的實現類,可以發現是log4j。

在這裡插入圖片描述

再用sc命令來檢視具體從哪個jar包里加載的:
在這裡插入圖片描述

可以看到log4j是通過slf4j代理的。

那麼通過org.slf4j.LoggerFactory獲取root logger,再修改它的level:
在這裡插入圖片描述

可以看到修改之後,root logger的level變為DEBUG。

怎樣減少測試小姐姐重複發請求的麻煩?

  • https://alibaba.github.io/arthas/tt.html

在平時開發時,可能需要測試小姐姐發請求過來聯調,但是我們在debug時,可能不小心直接跳過去了。這樣子就尷尬了,需要測試小姐姐再發請求過來。

Arthas裡提供了tt命令,可以減少這種麻煩,可以直接重放請求。

在這裡插入圖片描述

上面的tt -t命令捕獲到了3個請求。然後通過tt --play可以重放請求:

在這裡插入圖片描述

Dubbo執行時有哪些Filter? 耗時是多少?

  • https://alibaba.github.io/arthas/trace.html

Dubbo執行時會載入很多的Filter,那麼一個請求會經過哪些Filter處理,Filter裡的耗時又是多少呢?

通過Arthas的trace命令,可以很方便地知道Filter的資訊,可以看到詳細的呼叫棧和耗時。

在這裡插入圖片描述

Dubbo動態代理是怎樣實現的?

  • https://alibaba.github.io/arthas/jad.html
  • com.alibaba.dubbo.common.bytecode.Wrapper

通過Arthas的jad命令,可以看到Dubbo通過javaassist動態生成的Wrappr類的程式碼:
在這裡插入圖片描述

獲取Spring context

除了上面介紹的一些排查技巧,下面分享一個獲取Spring Context,然後“為所欲為”的例子。

在Dubbo裡有一個擴充套件
com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory,把Spring Context儲存到了裡面。

因此,我們可以通過ognl命令獲取到。

在這裡插入圖片描述

  • [email protected]獲取到SpringExtensionFactory裡儲存的spring context物件
  • #context.getBean(“userServiceImpl”).findUser(1) 獲取到userServiceImpl再執行一次呼叫

只要充分發揮想像力,組合Arthas裡的各種命令,可以發揮出神奇的效果。

最後

感謝大家看到這裡,文章有不足,歡迎大家指出;如果你覺得寫得不錯,那就給我一個贊吧。

也歡迎大家關注我的公眾號:程式設計師麥冬,麥冬每天都會分享java相關技術文章或行業資訊,歡迎大家關注和轉發文章!