中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Java在線問題排查利器之Btrace&Greys

2018-07-20    來源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用

1. 前言

前段時(shí)間升級(jí)了urs新的遠(yuǎn)程cookie校驗(yàn)?zāi)J。功能上線后,發(fā)現(xiàn)涉及用戶cookie 校驗(yàn)的接口,有時(shí)會(huì)報(bào)接口超時(shí)。通過日志埋點(diǎn)方式,確認(rèn)了與urs提供的jar包內(nèi)的新驗(yàn)證方法有關(guān)。通過反編譯,看到相關(guān)方法執(zhí)行過程中涉及參數(shù)校驗(yàn)、參數(shù)組裝、遠(yuǎn)程訪問校驗(yàn)、本地校驗(yàn)等步驟,究竟哪個(gè)步驟出了問題?

一種方式是讓urs幫忙提供一個(gè)新的jar包,在關(guān)鍵步驟處加日志,記錄執(zhí)行時(shí)間,另一種方法,就是使用一些在線分析工具。顯然第二種方式更方便快捷。本文主要介紹兩款在線問題排的工具: BtraceGreys 。

2. 工具簡介

Btrace和 Greys 都比較適合對(duì)生成環(huán)境的問題進(jìn)行排查,都屬于“事后工具” ,即服務(wù)已經(jīng)上線了,無法再通過打印日志等方式埋點(diǎn)分析。這時(shí)可以使用這些工具,來跟蹤代碼執(zhí)行耗時(shí)、堆棧情況等。

原理

都是基于動(dòng)態(tài)字節(jié)碼修改技術(shù)(Hotswap)來實(shí)現(xiàn)運(yùn)行時(shí) java 程序的跟蹤和替換。

利用了Java SE 6 新特性Instrumentation 。

使用場(chǎng)景

  • 分析哪些方法慢,查詢具體的故障點(diǎn);
  • 查看方法的參數(shù)、返回值;
  • 查看對(duì)象屬性等;

Btrace 和 Greys

Btrace 和 Greys 都屬于工具,本文以實(shí)例,介紹如何使用,不再對(duì)其本身進(jìn)行介紹,如果想進(jìn)一步了解,可以直接去下面的鏈接:

類型 介紹
Btrace https://github.com/btraceio/btrace/wiki
Greys介紹 https://yq.aliyun.com/articles/2390

3. 實(shí)例-使用工具排查問題

urs新提供了遠(yuǎn)程cookie的校驗(yàn)jar包,其中關(guān)鍵的方法為遠(yuǎn)程調(diào)用方法

CookieDecoder.requestDecode(**),我們主要對(duì)這個(gè)方法進(jìn)行跟蹤。

3.1 使用Btrace

由于我們的tomcat 在 appuser 用戶下,為了有相應(yīng)權(quán)限,我們的操作都在 appuser 用戶下進(jìn)行。

大體步驟分為:

  • 下載解壓 btrace 工具;
  • 編寫監(jiān)控腳本;
  • 設(shè)置jdk/btrace 環(huán)境變量,上傳腳本,編譯
  • 獲取tomcat 進(jìn)程號(hào)
  • 啟動(dòng)監(jiān)控
  • 查看詳情

具體操作:

(1)下載btrace工具 btrace-bin-1.3.9.tgz 并解壓縮

(2) 編寫一個(gè)監(jiān)控腳本(java代碼 UrsInterfaceCalls.java),

即需要監(jiān)控的具體類和方法

@BTrace                         // 備注1
public class UrsInterfaceCalls{
	
	/**
	 * 備注2
	 * 本代碼用于監(jiān)控 CookieDecoder 中 requestDecode 方法的執(zhí)行時(shí)間,如果執(zhí)行時(shí)間大于 500ms,則打印花費(fèi)的時(shí)間和堆棧
	 * @param duration
	 */
	@OnMethod(
			clazz="com.netease.urs.CookieDecoder",
			method="requestDecode",
			[email protected](Kind.RETURN))    // 備注2
    public static void requestDecode( @Duration long duration ) {   // 備注3
		//備注4
		if(duration /1000000 > 500){
			println("==CookieDecoder requestDecode spend: " + duration /1000000 + " ms");
			jstack();
		}
    }
	
	/**
	 * 本代碼用于監(jiān)控 CustomHttpComponent 中 execute 方法的執(zhí)行時(shí)間,如果執(zhí)行時(shí)間大于 500ms,則打印花費(fèi)的時(shí)間和堆棧
	 * @param duration
	 */
	@OnMethod(
			clazz="com.netease.urs.http.CustomHttpComponent",
			method="execute",
			[email protected](Kind.RETURN))
    public static void execute( @Duration long duration ) {
		if(duration /1000000 > 500){
			println("==ursCookieHttp doExecute spend: " + duration /1000000 + " ms");
			jstack();
		}
    }
}

簡要說明

本監(jiān)控類,寫了兩個(gè)監(jiān)控方法:

一個(gè)是監(jiān)聽CookieDecoder.requestDecode()的執(zhí)行時(shí)間,如果大于 500ms,則打印日志,并打印相關(guān)堆棧;

另一個(gè)監(jiān)聽CustomHttpComponent.execute()的執(zhí)行時(shí)間。

備注1:添加注釋 @BTrace ,代表本腳本將使用btrace相關(guān)功能;

備注2:攔截方法定義 ,@OnMethod 可以指定 clazz 、 method、location。由此組成了在什么時(shí)機(jī)(location 決定)監(jiān)控某個(gè)類/某些類(clazz 決定)下的某個(gè)方法/某些方法(method 決定)。

@OnMethod(clazz="com.netease.urs.CookieDecoder",method="requestDecode",[email protected](Kind.RETURN))

意思是監(jiān)控CookieDecoder.requestDecode() ,在執(zhí)行結(jié)束后([email protected](Kind.RETURN) 執(zhí)行相關(guān)操作。

備注3:@Duration 代表方法執(zhí)行時(shí)間,納秒。

備注4:只打印 耗時(shí)超過500ms的信息及堆棧,防止記錄打印大多。

方法注解說明

  • @OnMethod:指定使用當(dāng)前注解的方法應(yīng)該在什么情況下觸發(fā):
    • claszz屬性指定要匹配的類的全限定類名,可以用正則表達(dá)式;
    • method屬性指定要匹配的方法名稱,可以用正則表達(dá)式;
    • type屬性void(java.lang.String)可以用于匹配:public void funcName(String param) 中的方法入?yún)ⅲ?/li>
    • location屬性用@Location來表明,匹配了clazz,method情況,在方法執(zhí)行的何時(shí)去執(zhí)行腳本(前,后,異常,行,某個(gè)方法調(diào)用)
  • @OnTimer:指定一個(gè)定時(shí)任務(wù)
  • @OnExit:當(dāng)腳本運(yùn)行Sys.exit(code)時(shí)觸發(fā)
  • @OnError:當(dāng)腳本運(yùn)行拋出異常時(shí)觸發(fā)
  • @OnEvent:腳本運(yùn)行時(shí)Ctrl+C可以發(fā)送事件
  • @OnLowMemory:讓你指定一個(gè)閥值,內(nèi)存低于閥值觸發(fā)
  • @OnProbe:可以用一個(gè)xml文件來描述你想在什么時(shí)候觸發(fā)該方法

方法參數(shù)注解說明

  • @Self:目標(biāo)對(duì)象本身
  • @Retrun:目標(biāo)程序方法返回值(Kind.RETURN)
  • @ProbeClassName:目標(biāo)類名
  • @ProbeMethodName:目標(biāo)方法名
  • @targetInstance:@Location指定的clazz,method的目標(biāo)(Kind.CALL)
  • @targetMethodOrField:@Location指定的clazz,method的目標(biāo)的方法或字段(Kind.CALL)
  • @Duration:目標(biāo)方法執(zhí)行時(shí)間,單位是納秒,需要與 Kind.RETURN 或者 Kind.ERROR 一起使用

(3)設(shè)置jdk/btrace 環(huán)境變量

export JAVA_HOME=/home/jdk1.8.0
export JRE_HOME=/home/jdk1.8.0/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=$JAVA_HOME/bin:$PATH

export BTRACE_HOME=/home/appuser/bTrace
export PATH=$BTRACE_HOME/bin:$PATH

上傳監(jiān)控腳本 UrsInterfaceCalls.java 到服務(wù)器;

可以用 btracec 進(jìn)行預(yù)編譯,以保證代碼無誤

(4)獲取tomcat的執(zhí)行進(jìn)程號(hào) ps aux |grep “/fa.163.com”

(5)進(jìn)入U(xiǎn)rsInterfaceCalls.java所在目錄,啟動(dòng)btrace監(jiān)控,監(jiān)聽指定進(jìn)程號(hào)19504(即jvm的進(jìn)程號(hào))

sh btrace -p 2021 19054  UrsInterfaceCalls.java

-p 2021 :指定一個(gè)端口號(hào),防止多個(gè)執(zhí)行導(dǎo)致端口沖突;

19054 :要監(jiān)聽的進(jìn)程號(hào)

UrsInterfaceCalls.java :監(jiān)聽腳本

(6)查看結(jié)果

如果方法執(zhí)行超過500ms,會(huì)打印日志,同時(shí)打印堆棧;

==CookieDecoder requestDecode spend: 525 ms
com.netease.urs.CookieDecoder.requestDecode(CookieDecoder.java:64)
com.netease.urs.ntescode.validate_cookie_online(ntescode.java:49)
com.netease.common.util.CookieUtil.getUserInfoFromUrsRemoteCookie(CookieUtil.java:317)
com.netease.lottery.service.util.CookieUtilServiceImpl.getUserInfoFromUrsRemoteCookie(CookieUtilServiceImpl.java:88)
com.netease.lottery.service.util.CookieUtilServiceImpl$$FastClassByCGLIB$$1bd66cf1.invoke(<generated>)
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

.......

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1708)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)

如果要定位具體耗時(shí),需要對(duì)各個(gè)關(guān)鍵方法,都添加監(jiān)控腳本。

3.2 使用Greys

使用greys,無需編寫 腳步,它是命令交互式的,直接輸入命令指定監(jiān)控的類、方法。

但是每次只能監(jiān)控一個(gè)方法,不能像 Btrace,可以同時(shí)監(jiān)控多個(gè)方法。

使用過程大體步驟:

  • 下載解壓 Greys工具,安裝;
  • 設(shè)置jdk 環(huán)境變量
  • 獲取tomcat 進(jìn)程號(hào)
  • 啟動(dòng)監(jiān)控
  • 查看詳情

具體步驟:

(1)下載最新版本的Greys、解壓后,執(zhí)行安裝命令

sh ./install-local.sh

(2)設(shè)置環(huán)境變量

export JAVA_HOME=/home/jdk1.8.0
export JRE_HOME=/home/jdk1.8.0/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=$JAVA_HOME/bin:$PATH

(3)查詢 jvm的進(jìn)程號(hào),進(jìn)入greys安裝目錄,啟動(dòng)Greys

./greys.sh 10437

10437 為 jvm的進(jìn)程號(hào)

(4)啟動(dòng)后,就可以通過交互式命令方式,對(duì)指定的類、方法進(jìn)行分析。

使用help 可以看到各種命令。

(5)使用 trace命令 跟蹤指定類、方法的執(zhí)行時(shí)間、參數(shù)、返回值情況;

使用 help trace,查詢使用方式

例如:跟蹤C(jī)ookieDecoder類中 requestDecode()方法耗時(shí)超過500ms 的方法執(zhí)行情況:

trace  -n 2  com.netease.urs.CookieDecoder  requestDecode    '#cost>500'

-n 2 :代表只打印2次就退出(防止刷屏,影響性能);

com.netease.urs.CookieDecoder :監(jiān)聽的類名

requestDecode :監(jiān)聽的方法名

‘#cost>500’ : 打印條件為 耗時(shí)超過 500ms

執(zhí)行后,會(huì)顯示:

ga?>trace  -n 2  com.netease.urs.CookieDecoder  requestDecode    '#cost>10'
Press Ctrl+D to abort.
Affect(class-cnt:1 , method-cnt:2) cost in 262 ms.

代表動(dòng)態(tài)修改了一個(gè)類,對(duì)兩個(gè)方法(例如方法重載)進(jìn)行監(jiān)控,修改花費(fèi)262毫秒。

如果出現(xiàn)滿足條件的情況,則我們會(huì)看到打印結(jié)果:

`---+Tracing for : thread_name="http-nio-8003-exec-8" thread_id=0x7a;is_daemon=true;priority=5;
    `---+[5283,5283ms]com.netease.urs.CookieDecoder:requestDecode()
        +---[1,0ms]java.lang.System:nanoTime()
        +---[2,1ms]org.apache.http.client.methods.HttpPost:<init>(@39)
        +---[2,0ms]java.lang.StringBuffer:<init>(@41)
        +---[2,0ms]java.lang.StringBuffer:append(@42)
        +---[2,0ms]java.net.URLEncoder:encode(@43)
        +---[2,0ms]java.lang.StringBuffer:append(@43)
        +---[2,0ms]java.lang.StringBuffer:append(@44)
        +---[2,0ms]java.lang.StringBuffer:append(@45)
        +---[2,0ms]java.lang.StringBuffer:append(@46)
        +---[2,0ms]java.lang.StringBuffer:append(@47)
        +---[2,0ms]java.lang.StringBuffer:append(@48)
        +---[2,0ms]java.lang.Integer:<init>(@49)
        +---[2,0ms]java.lang.Integer:<init>(@49)
        +---[2,0ms]java.lang.reflect.Method:invoke(@49)
        +---[2,0ms]java.lang.StringBuffer:append(@49)
        +---[2,0ms]java.lang.StringBuffer:toString(@50)
        +---[2,0ms]org.apache.http.entity.StringEntity:<init>(@50)
        +---[2,0ms]org.apache.http.entity.StringEntity:setContentType(@51)
        +---[2,0ms]org.apache.http.client.methods.HttpPost:setEntity(@52)
        +---[2,0ms]org.apache.http.client.methods.HttpPost:getParams(@53)
        +---[2,0ms]org.apache.http.params.HttpParams:setIntParameter(@55)
        +---[2,0ms]org.apache.http.params.HttpParams:setIntParameter(@58)
        +---[5282,5280ms]com.netease.urs.http.CustomHttpComponent:execute(@60)
        +---[5283,0ms]org.apache.http.HttpResponse:getEntity(@61)
        +---[5283,0ms]org.apache.http.util.EntityUtils:toString(@62)
        +---[5283,0ms]com.netease.urs.util.LogUtil:debug(@63)
        +---[5283,0ms]org.apache.http.client.methods.HttpPost:releaseConnection(@71)
        +---[5283,0ms]java.lang.System:nanoTime(@64)
        `---[5283,0ms]com.netease.urs.CookieDecoder:$btrace$com$netease$fa$trace$UrsInterfaceCalls$2$requestDecode(@64)

可以看到,主要耗時(shí)在

+---[5282,5280ms]com.netease.urs.http.CustomHttpComponent:execute(@60)

只要一層一層跟蹤下去,就可以最終定位問題。

(6)退出前可以使用 reset 恢復(fù)增強(qiáng)類(即被動(dòng)態(tài)修改的代碼)

(7)最后,使用shutdown 關(guān)閉greys 并退出

4.總結(jié)說明

(1) 相比兩個(gè)工具,btrace 需要手寫腳步,每次更新都要重新上傳再執(zhí)行,而greys 支持命令式交互,無需手寫腳本;

(2)btrace 腳步中,可以寫多個(gè)監(jiān)聽類和方法,但是greys 命令同時(shí)只能輸入一個(gè)。(但是greys 可以支持多個(gè)用戶操作,所如果想同時(shí)監(jiān)控多個(gè)方法,只能開多窗口)

(3)btrace 要確保監(jiān)控腳本的正確性,使用前最好預(yù)編譯,防止動(dòng)態(tài)增強(qiáng)后影響在線功能;

(4)監(jiān)控時(shí),設(shè)置合適的條件,例如在 greys實(shí)例中,花費(fèi)時(shí)間大于 N ms才輸出,且只打印2個(gè)。

(5)greys 中只能顯示1層的方法調(diào)用情況,無法直接跟蹤到最底層;只能自己一層一層往下跟進(jìn)。

 

來自:http://tech.lede.com/2017/10/11/rd/server/javaToolsBTrace/

 

標(biāo)簽: swap 代碼 服務(wù)器 腳本 權(quán)限

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:稀疏 & 集成的卷積神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)

下一篇:iOS中的MVP模式初探