Java面試題~面試官:你是怎么定位、排查、診斷生產(chǎn)環(huán)境的Bug的?

作者: 修羅debug
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。


作為一名Java程序猿,“溝通需求”、“設(shè)計(jì)數(shù)據(jù)庫(kù)”、“建表”以及“編碼開發(fā)”是家常便飯的事,每天幾乎都得重復(fù)性干這樣的活,有的甚至還樂此不彼?。ó?dāng)然啦,前提是錢給到位了~~);但若要問起他們對(duì)什么東西相當(dāng)敏感、甚至偶爾還會(huì)出現(xiàn)反感的話,那當(dāng)屬Bug和一些疑難雜癥 無疑了!而如何在線上生產(chǎn)環(huán)境快速定位、排查以及診斷相應(yīng)的Bug、解決相應(yīng)的疑難雜癥便成為了一個(gè)值得探討的話題,話不多說,咱們直接進(jìn)入正文?。?!

    先不繞彎子,咱們直接先說答案吧:借助Alibaba開源的Java診斷工具Arthas可以快速直觀地定位、排查、診斷生產(chǎn)環(huán)境中的Bug;

      這時(shí)候就有小伙伴可能會(huì)問了,這家伙是啥玩意?怎么就可以快速定位、排查、診斷生產(chǎn)環(huán)境的Bug?它在實(shí)際生產(chǎn)環(huán)境中又是怎么用的呢?能不能來點(diǎn)實(shí)際的???……   


    別急啊,容debug娓娓道來………先說說Arthas是啥玩意吧:

    這家伙是“Alibaba開源的Java應(yīng)用線上診斷工具,深受開發(fā)者喜愛”,這是Arthas的官方定義,enenen……這丫的也太短了吧………,算了,大道至簡(jiǎn),這絲毫不影響debug對(duì)它的愛慕,感興趣的小伙伴可以點(diǎn)擊其開源地址:

(1)https://github.com/alibaba/arthas/blob/master/README_CN.md  

(2)https://gitee.com/arthas/arthas

附注:有些小伙伴可能訪問不了github,沒關(guān)系,點(diǎn)擊第(2)個(gè)鏈接,那是debug專門為大伙兒找的對(duì)應(yīng)的碼云的地址;   


接下來,我們來看一下Arthas可以解決什么樣的問題?直接看官網(wǎng)的介紹吧:


    毋庸置疑,這是一款強(qiáng)大而且好用的線上診斷工具,若用得好,相信可以干掉許多線上生產(chǎn)環(huán)境的疑難雜癥,特別是在前后端分離開發(fā)、部署的模式下,諸如 快速定位前端傳遞的參數(shù)、查看接口返回的結(jié)果、查看接口執(zhí)行的方法路徑及其對(duì)應(yīng)的耗時(shí)、監(jiān)控整個(gè)Java應(yīng)用的內(nèi)存/CPU等指標(biāo)的占用等情況,在Arthas面前可以說是小菜一碟


    那么在實(shí)際生產(chǎn)環(huán)境中該如何使用呢?還是來點(diǎn)實(shí)際的吧:

1)這里我們以Linux環(huán)境中部署的“程序員實(shí)戰(zhàn)基地 fightjava.com” 的課程中心 板塊的接口為案例,一同學(xué)習(xí)并實(shí)戰(zhàn)Arthas在實(shí)際生產(chǎn)環(huán)境中的使用;其中這個(gè)接口的方法所在的全限定類名為:

com.debug.coding.fight.server.controller.web.IndexCourseController.center()

對(duì)應(yīng)的完整的代碼如下所示:

@RestController
public class IndexCourseController extends IndexWebAbstractController{

private static final Logger log= LoggerFactory.getLogger(IndexCourseController.class);

//首頁(yè)課程中心
@RequestMapping(value = prefix + "/center", method = RequestMethod.GET)
public BaseResponse center(@Validated IndexCourseQuery query, BindingResult result){
if (result.hasErrors() || query.getPageNo() <= 0 || query.getPageSize() <= 0) {
return new BaseResponse(StatusCode.InvalidParams);
}
BaseResponse response = new BaseResponse(StatusCode.Success);
try {
//其中indexCourseService.indexCourseCenter(query)為具體執(zhí)行的代碼邏輯
response.setData(indexCourseService.indexCourseCenter(query));
} catch (Exception e) {
return new BaseResponse(StatusCode.Fail.getCode(), e.getMessage());
}
return response;
}
}

    其中,該方法的請(qǐng)求參數(shù)為IndexCourseQuery,其定義如下所示:

@Data
@ToString
public class IndexCourseQuery implements Serializable {
@NotNull
private Integer pageNo=1;
@NotNull
private Integer pageSize=Constant.COURSE_CENTER_PAGE_SIZE;

private String search;
private Integer typeId;
}

    而響應(yīng)結(jié)果是塞到BaseResponse類中的,其結(jié)果是indexCourseService服務(wù)類調(diào)用indexCourseCenter()方法返回的,類型為:Map<String, Object>,里面有許多核心數(shù)據(jù),在這里就不貼出來了,大伙兒可以訪問https://www.fightjava.com/ 然后,點(diǎn)擊課程中心,F12即可看到請(qǐng)求接口鏈接后返回的響應(yīng)結(jié)果:


2OK,介紹了那么多,可能有些小伙伴有疑惑“這跟Arthas有啥關(guān)系?” 實(shí)不相瞞,還真有關(guān)系,因?yàn)?span lang="EN-US">debug將以這個(gè)板塊、接口為案例,基于Linux環(huán)境查看整個(gè)Java應(yīng)用的資源分配情況、接口調(diào)用的入?yún)?、接口返回的結(jié)果、接口方法調(diào)用的路徑及其對(duì)應(yīng)的耗時(shí)………那就直接來吧!   


3)首先,先執(zhí)行以下命令,將Arthas診斷工具下載到Linux環(huán)境某個(gè)目錄(也可以前往這個(gè)鏈接手動(dòng)進(jìn)行下載然后上傳到服務(wù)器的某個(gè)文件目錄下:http://fightjava.com/web/index/resource/17),然后將其啟動(dòng),命令如下所示:

curl -O https://arthas.aliyun.com/arthas-boot.jar

java -jar arthas-boot.jar

    稍等片刻,即可成功啟動(dòng),如下圖所示:


4)試試dashboard命令吧,可以查看“程序員實(shí)戰(zhàn)基地官網(wǎng)”這一Java應(yīng)用的線程、內(nèi)存、GC以及運(yùn)行時(shí)相關(guān)信息(JDK版本等等),如下圖所示:


5)接下來是比較常用的trace 命令:查看接口方法中的調(diào)用路徑以及相關(guān)耗時(shí)情況;先按下ctrl+c,終止上次命令的結(jié)果查看,然后鍵入命令:

trace  com.debug.coding.fight.server.controller.web.IndexCourseController center

回車進(jìn)入等待狀態(tài),如下圖所示:


    然后在postman發(fā)起上述接口的調(diào)用,在這里,因?yàn)樵摻涌趯?duì)應(yīng)的是程序員實(shí)戰(zhàn)基地官網(wǎng)的“課程中心”首頁(yè):https://www.fightjava.com/web/index/course.html ,因此debug就直接打開瀏覽器訪問了,之后,回到上圖的命令行界面,可以看到結(jié)果了,如下圖所示:


    可以看到,該請(qǐng)求方法內(nèi)部有分叉開了幾條調(diào)用路徑,其中紅色的表示耗時(shí)最長(zhǎng)的,即IIndexCourseService服務(wù)類下的indexCourseCenter()請(qǐng)求方法,如下所示:

com.debug.coding.fight.server.service.web.IIndexCourseService:indexCourseCenter()

    在這里因?yàn)楹臅r(shí)才8.x毫秒,因此也不算太長(zhǎng),在這里就沒必要跟蹤下去了;倘若該該調(diào)用鏈耗時(shí)達(dá)到幾秒或者十幾秒,那就需要再次使用該命令再次對(duì)其進(jìn)行跟蹤:

trace  debug.coding.fight.server.service.web.IIndexCourseServic  indexCourseCenter

    利用此命令,可以知曉一個(gè)請(qǐng)求方法中到底是哪個(gè)子調(diào)用鏈響應(yīng)慢或者出問題了!

6)緊接著是debug經(jīng)常用到的核心命令:watch 了,其詳細(xì)的文檔可以看這里:https://arthas.aliyun.com/doc/watch ,下面debug帶諸位一起感受一下它的常見用法!

    A.首先是查看該請(qǐng)求中前端傳遞到后端接口的參數(shù)列表,命令如下所示:

watch com.debug.coding.fight.server.controller.web.IndexCourseController center {params} -x 2

    其中,{}中的params代表該命令將查看該接口方法的入?yún)ⅲ?span lang="EN-US">-x 2表示顯示出兩個(gè)層級(jí)的內(nèi)容;需要說明的是 params為數(shù)組類型,表示參數(shù)數(shù)組,上述IndexCourseController類中的center方法擁有兩個(gè)參數(shù),因此它的size=2,該控制器類的方法定義如下圖所示:


    返回結(jié)果如下所示:


    從該結(jié)果中就可以很直截了當(dāng)?shù)闹獣郧岸藗鬟f過來了什么參數(shù),如果將 –x 2 調(diào)整為 –x 3,那么將可以看到BindingResult 中的詳細(xì)參數(shù)了!

    B.如果還想看到該接口的請(qǐng)求方法最終返回的結(jié)果,則可以通過如下的命令查看:

watch com.debug.coding.fight.server.controller.web.IndexCourseController center {params,returnObj} -x 2

    其返回結(jié)果如下所示:


      C.上圖該結(jié)果,我只是看到了response中的hashMap,那里面是啥東西呢,別急,可以執(zhí)行這一命令查看更多層級(jí)的內(nèi)容:   

watch com.debug.coding.fight.server.controller.web.IndexCourseController center {returnObj} -x 5

    其返回結(jié)果如下所示:


7)除此之外,還有 tt –t 命令、Monitor命令、Thread、jad、mc、ClassLoader等命令,這幾個(gè)debug用得倒不是很多,因此就不介紹了,感興趣的小伙伴可以自行前往其開源的官網(wǎng)照著擼一下!

 至此,debug算是將Java應(yīng)用線上診斷工具Arthas介紹完了,雙11快到了,建議可以上阿里云采購(gòu)一臺(tái)ECS(新用戶聽說0.95折),然后自建一個(gè)項(xiàng)目,寫幾個(gè)接口最后部署上ECS服務(wù)器,最后再按照本文debug介紹的一步步實(shí)戰(zhàn)Arthas吧!??!


總結(jié)

本文我們一起擼下了一個(gè)Java應(yīng)用常用的線上診斷工具Arthas,毫不客氣地講,這家伙偶爾還是可以起到神助攻的作用,因此強(qiáng)烈建議各位小伙伴拿下它!好了,本文就介紹到這里了吧,我是debug,一個(gè)相信技術(shù)改變生活、技術(shù)成就夢(mèng)想 的直男屌絲?。?!

如果本文對(duì)你有幫助,請(qǐng)關(guān)注公眾號(hào),并動(dòng)動(dòng)手指收藏、點(diǎn)贊、以及轉(zhuǎn)發(fā)哦!?。?nbsp;  

備注:上述下載鏈接如果失效,可以加debug微信:debug0868  告知并領(lǐng)取(想學(xué)習(xí)更多的技術(shù)干貨可以關(guān)注debug的技術(shù)公眾號(hào),不迷路)?。?!