使用Arthas獲取Spring應用上下文的2種方法
背景
專案中有時我們需要對應用進行診斷和除錯,如呼叫某個介面進行業務驗證、業務執行、資料修復、重新整理快取、查詢資料、跑批量任務等等。
-
微服務專案
如基於Dubbo搭建的微服務,我們可使用Dubbo支援的telnet運維管理,其中invoke命令方便直接呼叫Dubbo介面;
也可整合swagger-dubbo,方便在網頁介面上直接呼叫Dubbo介面。 -
web專案
如使用了SpringMVC、Jersey等框架,可考慮暴露一些運維相關的內部rest api,裡面呼叫業務方法,用於某些場景下人工操作處理。
有些情況下以上條件不具備,如不能修改程式碼、希望不修改程式碼、不方便修改程式碼、沒有原始碼等原因。
Arthas
Arthas 是Alibaba開源的Java診斷工具,可以用於快速診斷Java應用和定位分析問題。
官網:https://arthas.aliyun.com
實戰
專案一般都是基於Spring/SpringBoot來構建,如果我們能獲取spring的ApplicationContext
,就能方便獲取spring容器的Bean,然後呼叫裡面的方法。
啟動Arthas:java -jar arthas-boot.jar
,選擇應用。
- 方法1
通過Dubbo的SpringExtensionFactory
來獲取
(1). 先掃描類,-d
引數表示獲取詳細資訊sc -d com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
注意結果裡的
classLoaderHash
值。
(2). 通過ognl命令,-c
引數指定ClassLoader的hash值,即上一步的classLoaderHash
值。ognl -c 6b884d57 '@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next'
觀察輸出結果,此時已成功獲取到Spring的ApplicationContext
,接下來可以根據場景和需要靈活使用了。
例如,呼叫某service方法:ognl -c 6b884d57 '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next,#context.getBean("songService").findRandomSongList(5)'
- 方法2
通過實現ApplicationContextAware
介面來獲取
(1). 專案中有一個實現了ApplicationContextAware
介面的類
例如:
package com.cdfive.common.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* @author cdfive
*/
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext APPLICATION_CONTEXT;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
APPLICATION_CONTEXT = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return APPLICATION_CONTEXT;
}
public static <T> T getBean(Class<T> beanType) {
return getApplicationContext() != null ? getApplicationContext().getBean(beanType) : null;
}
public static Object getBean(String beanName) {
return getApplicationContext() != null ? getApplicationContext().getBean(beanName) : null;
}
}
(2). 掃描類,-d
引數表示獲取詳細資訊sc -d com.xxx.SpringContextUtil
(3). 呼叫類裡獲取ApplicationContext
的方法ognl -c 6b884d57 '@com.cdfive.common.util.SpringContextUtil@getApplicationContext()'
觀察輸出結果,此時已成功獲取到Spring的ApplicationContext
,接下來可以根據場景和需要靈活使用了。
例如,呼叫某service方法:ognl -c 6b884d57 '#[email protected]@getApplicationContext(),#context.getBean("songService").findRandomSongList(5)'
注:方法1需要應用使用了Dubbo框架,方法2則應用範圍更廣,應用使用了Spring框架即可。
思考
通過Arthas,我們可方便的對Java應用進行分析和診斷,對於測試和線上問題分析和定位很有幫助,並且很大提高了效率;
同時也應注意到安全因素,開發、測試環境還好,線上環境由於正在被使用,開發人員直接操作線上介面有一定風險;
操作失誤可能破壞線上資料的完整性,影響系統穩定等等,因此使用上需要有所限制。比如分析線上疑難問題,限制僅呼叫查詢資料的介面;
當有更新資料的需求時,考慮介面的冪等性、做好資料備份、二次確認等,避免在分析線上問題反而造成新的問題,要有避免線上事故的高度警惕。
此外,基於Arthas定製二次開發的系統,或者跟開發IDE結合的外掛,可以更好的滿足需求,使用上也會更加高效、安全、智慧。
參考業內已有的技術分享:
- 工商銀行打造線上診斷平臺的探索與實踐 https://developer.aliyun.com/article/775898
- arthas idea plugin 外掛,arthas 使用更加絲滑起來 https://blog.csdn.net/u012881904/article/details/103865802