全部產品
Search
文件中心

Application Real-Time Monitoring Service:使用代碼熱點診斷慢調用鏈的問題

更新時間:Jul 06, 2024

ARMS代碼熱點作為一種監控診斷工具,通過持續剖析技術定時採集請求線程堆棧快照,真實還原代碼執行的第一現場。

使用情境

  • 當促銷活動出現慢調用時,ARMS代碼熱點可為您快速定位問題代碼。

  • 當系統出現大量慢調用時,ARMS代碼熱點可為您自動儲存第一現場。

  • 當業務太複雜,偶發性慢調用無法複現時,ARMS代碼熱點可為您還原代碼真實方法層面的執行軌跡。

  • 當調用鏈中因為缺失對應用代碼非架構層面的方法埋點時,代碼熱點幫您還原對應缺失埋點的實際方法調用耗時。

前提條件

  • 代碼熱點功能需要使用3.1.4或以上版本的探針。

  • 代碼熱點功能依賴持續剖析能力,對作業系統核心和JDK版本有一定的要求,請參見使用限制,選擇合適的作業系統與JDK。

  • 目前僅同步調用的調用鏈支援使用代碼熱點功能,包含非同步呼叫的調用鏈暫不支援。

開啟代碼熱點

  1. 登入ARMS控制台,在左側導覽列選擇應用監控 > 應用列表

  2. 應用列表頁面頂部選擇目標地區,然後單擊目標應用程式名稱。

    說明

    語言列的表徵圖含義如下:

    Java表徵圖:接入應用監控的Java應用。

    image:接入應用監控的Golang應用。

    -:接入Managed Service for OpenTelemetry的應用。

  3. 在左側導覽列中單擊應用設定,然後單擊自訂配置頁簽。

  4. 持續剖析地區開啟總開關,然後開啟代碼熱點開關,配置需要開啟的應用執行個體的IP地址或者一組執行個體所屬的網段地址。

  5. 在頁面底部單擊儲存

    無需重啟應用即可生效。

通過介面調用查看代碼熱點資料

樣本:解析並遍曆JSON資料及調用下遊HTTP介面。

public class HotSpotAction extends AbsAction {

  private RestTemplate restTemplate = new RestTemplate();
  
  //請求入口方法
  @Override
  public void runBusiness() {
    readFile();
    invokeAPI();
  }

  //執行HTTP調用
  private void invokeAPI() {
    String url = "https://httpbin.org/get";
    String response = restTemplate.getForObject(url, String.class);
  }

   //讀取檔案資料並解析
  private double readFile() {
    InputStreamReader reader = new InputStreamReader(
        ClassLoader.getSystemResourceAsStream("data/xxx.json"));
    LinkedList<Movie> movieList = GSON.fromJson(reader, new TypeToken<LinkedList<Movie>>() {
    }.getType());
    double totalCount = 0;
    for (int i = 0; i < movieList.size(); i++) {
      totalCount += movieList.get(i).rating();
    }
    return totalCount;
  }
}
  1. 登入ARMS控制台,在左側導覽列選擇應用監控 > 應用列表

  2. 應用列表頁面頂部選擇目標地區,然後單擊目標應用程式名稱。

    說明

    語言列的表徵圖含義如下:

    Java表徵圖:接入應用監控的Java應用。

    image:接入應用監控的Golang應用。

    -:接入Managed Service for OpenTelemetry的應用。

  3. 在左側導覽列中單擊介面調用,並在頁面右側選擇目標介面,然後單擊調用鏈查詢頁簽。

  4. 調用鏈查詢頁簽上單擊目標TraceId連結。

  5. 詳情列中單擊放大鏡表徵圖,然後單擊代碼熱點頁簽。

    image

    圖中左側為本次調用中所涉及的所有方法耗時情況列表,右側為對應方法所有方法棧資訊繪製的火焰圖。其中:

    • Self列表示方法在自身的調用棧中所消耗的時間或資源,不包括其子方法調用所消耗的時間或資源。可以用於識別哪些方法在自身內部花費了大量的時間或資源。

    • Total列包含方法自身消耗的時間或資源,及其所有子方法調用所消耗的時間或資源。可以協助瞭解整個方法調用棧中哪些方法貢獻了最多的時間或資源。

    作為排查具體的熱點代碼邏輯,可以通過重點關注Self列或直接查看右側火焰圖中底部的較寬火苗從中定位到高耗時的業務方法,較寬火苗是引發上層耗時高的根源,一般是系統效能的瓶頸所在,例如上圖中的java.lang.Thread.sleep()方法。

    根據上圖,進行如下分析:

    1. 將Self值從大到小排列,找到並單擊Self值最大的方法java.util.LinkedList.node(int),右側火焰圖中將會聚焦相關方法。

      image

    2. 聚焦後可以發現,java.util.LinkedList.node(int)就是右側火焰圖中的最寬棧頂方法。

    3. 由於該棧頂是JDK中的庫函數,並非為業務方法,因此,沿著棧頂方法java.util.LinkedList.node(int)從下往上搜尋,依次經過java.util.LinkedList.get(int) > com.alibaba.cloud.pressure.memory.HotSpotAction.readFile(),而com.alibaba.cloud.pressure.memory.HotSpotAction.readFile()屬於所分析應用的業務方法,即為第一個所分析應用自身定義的方法行,其耗時為3.75s,占整張火焰圖的69.88%,因此com.alibaba.cloud.pressure.memory.HotSpotAction.readFile()是該火焰圖所採集時段內資源佔用較高的顯著瓶頸所在,可以根據該方法名,對業務中相關方法的邏輯進行梳理,查看是否存在最佳化空間。

常見問題

  • 代碼熱點的耗時為什麼會出現小於本次請求耗時情況?

    為了儘可能降低代碼熱點功能對應用效能的影響,我們引入了採集最佳化機制,這會導致統計到的耗時小於實際的請求耗時。統計偏差一般在20毫秒內,您可以忽略絕對值的偏差,重點關注相對耗時最高的方法。

  • 代碼熱點的統計範圍是否有限制?

    • 對於耗時超過15分鐘的請求,代碼熱點功能僅提供前15分鐘的分析資料。

    • 對於低耗時請求(一般在500ms以下,根據系統負載動態決策),為了降低系統開銷,ARMS不會觸發代碼熱點資料統計,因此,可能會出現頁簽中無資料的現象。