日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

增压的jstack:如何以100mph的速度调试服务器

發(fā)布時(shí)間:2023/12/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 增压的jstack:如何以100mph的速度调试服务器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用jstack調(diào)試實(shí)時(shí)Java生產(chǎn)服務(wù)器的指南

jstack就像U2一樣-從時(shí)間的黎明就一直在我們身邊,我們似乎無法擺脫它 。 除了笑話,到目前為止,jstack是您調(diào)試軍用生產(chǎn)服務(wù)器中最方便的工具之一。 即便如此,我仍然認(rèn)為它在情況惡化時(shí)能夠?qū)⒛鷱幕鹬袚錅绲哪芰θ晕吹玫匠浞掷?#xff0c;因此我想分享一些方法,您可以在對(duì)抗生產(chǎn)錯(cuò)誤的戰(zhàn)爭(zhēng)中將其增壓為更強(qiáng)大的武器。

jstack的核心是一個(gè)超級(jí)簡(jiǎn)單的工具,它向您顯示在目標(biāo)JVM中運(yùn)行的所有Java線程的堆棧跟蹤。 只需通過一個(gè)pid將其指向JVM進(jìn)程即可獲得該時(shí)間點(diǎn)所有線程堆棧跟蹤的打印輸出。 這使您能夠回答“這個(gè)服務(wù)器在做什么?”這個(gè)古老的問題,并使您更進(jìn)一步地了解它為什么真正在做它。 關(guān)于jstack的最大優(yōu)點(diǎn)是它輕巧–它不會(huì)給JVM增加任何性能開銷,也不會(huì)更改其執(zhí)行狀態(tài)(與調(diào)試器或探查器不同)。

由于沒有什么是完美的 ,因此jstack有兩個(gè)明顯的缺點(diǎn)。 第一個(gè)是jstack除了調(diào)用堆棧外沒有為您提供任何變量狀態(tài),這意味著盡管您可能正在查看堆棧,但您不知道將其置于何處的狀態(tài)。 一個(gè)很好的例子是查看掛起的JVM,其中jstack會(huì)向您顯示大量線程正在執(zhí)行數(shù)據(jù)庫(kù)查詢或等待獲得連接。

這可能意味著某些查詢執(zhí)行時(shí)間太長(zhǎng),導(dǎo)致其他線程要么等待連接,要么被拒絕。 在這里,您真的想知道正在執(zhí)行的查詢(或查詢的參數(shù)是什么)會(huì)導(dǎo)致速度下降以及何時(shí)開始。 當(dāng)然,這只是一個(gè)例子,在很多情況下,其中某些線程被阻塞并降低了應(yīng)用程序的吞吐量。 但是不幸的是,使用jstack時(shí),因?yàn)槟鷽]有獲得任何變量狀態(tài),所以您無法真正確定應(yīng)歸咎于哪個(gè)線程。 還是可以嗎?

jstack的第二個(gè)缺點(diǎn)是它不是永遠(yuǎn)在線的工具。 這意味著,當(dāng)問題發(fā)生時(shí),您必須在那里-在生產(chǎn)中這是罕見的事件。 在不斷重啟VM的彈性環(huán)境中,這一點(diǎn)更為真實(shí)。

好的部分到了–讓我們看一下兩種技術(shù),它們可以幫助我們克服這兩個(gè)缺點(diǎn),并使一個(gè)好的工具真正變得很棒。

創(chuàng)建有狀態(tài)線程數(shù)據(jù)

第一個(gè)問題是如何向jstack打印輸出添加狀態(tài)? 答案簡(jiǎn)單而強(qiáng)大-線程名稱。 盡管許多人錯(cuò)誤地認(rèn)為線程名稱是不可變的,或者是操作系統(tǒng)確定的屬性,但實(shí)際上,每個(gè)線程都具有可變的且非常重要的特征。 這也是進(jìn)入您的jstack流的關(guān)鍵所在。

實(shí)際的應(yīng)用程序就像日志記錄一樣,一旦它通過諸如servlet,actor或Scheduler之類的入口點(diǎn)輸入代碼,就應(yīng)該控制線程名。 此時(shí),您需要將其名稱設(shè)置為一個(gè)有意義的值,該值可以幫助您了解執(zhí)行上下文和相關(guān)參數(shù),從而可以幫助您隔離事務(wù)及其內(nèi)容。

這很可能包括–

  • 線程的用途(例如,處理消息,響應(yīng)用戶請(qǐng)求等)。
  • 使用事務(wù)ID,您可以識(shí)別跨不同機(jī)器和應(yīng)用程序各部分的此特定數(shù)據(jù)流。
  • 參數(shù)值,例如servlet參數(shù)或要出隊(duì)的消息的ID。
  • 獲得線程控制的時(shí)間。 對(duì)于使用jstack觀察它們時(shí),確切地知道代碼中的哪些線程被卡住,最后一項(xiàng)至關(guān)重要。
  • Thread.currentThread().setName(Context + TID + Params + current Time,..);

    這些數(shù)據(jù)將意味著查看打印輸出(例如下面的打印輸出實(shí)際上并不能告訴我們?nèi)魏尉€程在做什么或?yàn)槭裁?#xff09;與提供信息的輸出之間的區(qū)別:

    “ pool-1-thread-1”#17 prio = 5 os_prio = 31 tid = 0x00007f9d620c9800 nid = 0x6d03 in Object.wait()[0x000000013ebcc000]

    將此與以下線程打印輸出進(jìn)行比較:

    “隊(duì)列處理線程,MessageID:AB5CAD,類型:AnalyzeGraph,隊(duì)列:ACTIVE_PROD,Transaction_ID:5678956,開始時(shí)間:2014/10/8 18:34”

    #17 prio = 5 os_prio = 31 tid = 0x00007f9d620c9800 nid = 0x6d03 in Object.wait()[0x000000013ebcc000]

    您在這里看到的是對(duì)該線程實(shí)際作用的更全面的解釋。 您可以輕松地從AWS隊(duì)列中查看其出隊(duì)消息,它正在分析該消息,其類型,ID和事務(wù)ID。 最后,但并非最不重要–線程何時(shí)開始對(duì)其進(jìn)行處理。 這可以幫助您非常快速地將注意力集中在那些被卡住的線程上,并查看它們所處的狀態(tài)。從那以后,在本地進(jìn)行優(yōu)化和復(fù)制將變得更加容易。

    這里的替代方案是要么希望日志文件中有數(shù)據(jù),而且能夠?qū)⑷罩局械臄?shù)據(jù)關(guān)聯(lián)到該確切線程。 另一個(gè)選擇是在生產(chǎn)環(huán)境中本地或遠(yuǎn)程連接調(diào)試器。 既不是很愉快又很費(fèi)時(shí)間。

    在線程名稱中寫入此信息也有助于傳統(tǒng)日志記錄。 即使大多數(shù)日志記錄框架都提供了可以添加到日志中的基于線程的上下文,您也必須確保正確配置它。 使用線程名稱還可以確保您將在日志中擁有所需的所有數(shù)據(jù)。

    注意:有些人可能會(huì)說不要修改或更改線程名稱。 根據(jù)我多年的個(gè)人經(jīng)驗(yàn)以及許多同事的經(jīng)驗(yàn),我對(duì)此非常信奉。

    使jstack始終在線

    使用jstack時(shí),我們面臨的第二個(gè)挑戰(zhàn)是,就像調(diào)試器一樣,它是您必須在發(fā)生問題時(shí)立即手動(dòng)捕獲損壞狀態(tài)的工具。 但是,當(dāng)服務(wù)器掛起或低于或低于某個(gè)特定閾值時(shí),有一種更活躍的方法可以使用jstack自動(dòng)生成打印輸出。 關(guān)鍵是要以編程方式調(diào)用jstack,就像在滿足特定應(yīng)用程序條件時(shí)從JVM中的任何日志記錄功能一樣。
    這里的兩個(gè)主要挑戰(zhàn)是何時(shí)以及如何實(shí)現(xiàn)。

    如何以編程方式激活jstack?

    由于jstack是一個(gè)普通的OS進(jìn)程,因此調(diào)用它非常簡(jiǎn)單。 您要做的就是激活jstack進(jìn)程并將其指向您自己。 這里的關(guān)鍵是如何從JVM中獲取進(jìn)程的pid。 實(shí)際上,沒有標(biāo)準(zhǔn)的Java API可以做到這一點(diǎn)( 至少要等到Java 9才可以 )。 這是完成工作的一小段代碼(盡管它不是已記錄的api的一部分):

    String mxName = ManagementFactory.getRuntimeMXBean().getName();int index = mxName.indexOf(PID_SEPERATOR);String result;if (index != -1) {result = mxName.substring(0, index); } else {throw new IllegalStateException("Could not acquire pid using " + mxName); }

    另一個(gè)小挑戰(zhàn)是將jstack輸出定向到您的日志中。 使用輸出流檢流器也很容易設(shè)置。 在此處查看有關(guān)如何將您調(diào)用的進(jìn)程輸出的輸出數(shù)據(jù)定向到日志文件或輸出流中的示例。

    盡管可以使用getAllStackTraces在內(nèi)部捕獲正在運(yùn)行的線程的堆棧跟蹤,但出于多種原因,我更喜歡通過運(yùn)行jstack來執(zhí)行此操作。 首先,這是我通常希望在正在運(yùn)行的應(yīng)用程序外部進(jìn)行的操作(即使JVM正在參與提供信息),以確保我不會(huì)通過內(nèi)省調(diào)用來影響應(yīng)用程序的穩(wěn)定性。 另一個(gè)原因是,jstack在功能方面更為強(qiáng)大,例如向您顯示本機(jī)框架和鎖定狀態(tài),而這在JVM中是不可用的。

    什么時(shí)候激活jstack?

    您需要做出的第二個(gè)決定是在什么條件下您希望JVM記錄jstack。 當(dāng)服務(wù)器低于或高于特定處理(即請(qǐng)求或消息處理)閾值時(shí),可能會(huì)在預(yù)熱期之后執(zhí)行此操作。 您可能還需要確保每次激活之間都花費(fèi)足夠的時(shí)間。 只是為了確保您不會(huì)在低負(fù)載或高負(fù)載下泛濫日志。

    您將在此處使用的模式是從JVM內(nèi)加載看門狗線程,該線程可以定期查看應(yīng)用程序的吞吐量狀態(tài)(例如,最近兩分鐘內(nèi)處理的消息數(shù)),并確定是否對(duì)屏幕進(jìn)行“截屏”。線程狀態(tài)將很有幫助,在這種情況下,它將激活jstack并將其記錄到文件中。

    設(shè)置該線程的名稱以包含目標(biāo)吞吐量和實(shí)際吞吐量狀態(tài),因此當(dāng)您執(zhí)行自動(dòng)jstack快照時(shí),您可以確切地看到看門狗線程決定這樣做的原因。 由于這只會(huì)每隔幾分鐘發(fā)生一次,因此該過程沒有實(shí)際的性能開銷,尤其是與所提供數(shù)據(jù)的質(zhì)量相比。

    下面的代碼片段顯示了這種模式的實(shí)際效果。 startScheduleTask加載看門狗線程以定期檢查吞吐量值,該吞吐量值在處理消息時(shí)使用Java 8 并發(fā)加法器遞增。

    public void startScheduleTask() {scheduler.scheduleAtFixedRate(new Runnable() {public void run() {checkThroughput();}}, APP_WARMUP, POLLING_CYCLE, TimeUnit.SECONDS); }private void checkThroughput() {int throughput = adder.intValue(); //the adder in inc’d when a message is processedif (throughput < MIN_THROUGHPUT) {Thread.currentThread().setName("Throughput jstack thread: " + throughput);System.err.println("Minimal throughput failed: exexuting jstack");executeJstack(); //see the code on github to see how this is done}adder.reset(); }
    • 在此處可以找到從代碼中搶占調(diào)用jstack的完整源代碼。

    翻譯自: https://www.javacodegeeks.com/2014/10/supercharged-jstack-how-to-debug-your-servers-at-100mph.html

    總結(jié)

    以上是生活随笔為你收集整理的增压的jstack:如何以100mph的速度调试服务器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。