剖析 Java 應用程式

本頁說明如何修改 Java 應用程式以擷取剖析資料,並將那些資料傳送至您的 Google Cloud Platform (GCP) 專案。如需剖析作業的一般資訊,請參閱剖析概念一文。

Java 適用的剖析類型:

  • CPU 作業時間
  • 堆積 (Alpha 版,需要 Java 11 和 App Engine 標準環境)
  • 實際時間 (不適用於 App Engine 標準環境)

支援的 Java 語言版本:

  • 適用於 Java 7、8、9 或 11 的 OpenJDK 和 Oracle JDK。

支援的作業系統:

  • 使用 glibc 實作標準 C 程式庫的 Linux 版本。

支援的環境:

啟用 Profiler API

使用剖析代理程式之前,請確保基礎 Profiler API 已啟用。您可以查看 API 狀態,或視需要使用 Cloud SDK gcloud 指令列工具或 Cloud Console 來啟用 API。

Cloud SDK

  1. 如果您尚未在工作站上安裝 Cloud SDK,請參閱 Google Cloud SDK

  2. 執行下列指令:

    gcloud services enable cloudprofiler.googleapis.com
    

詳情請參閱 gcloud services 一文。

Cloud Console

  1. 前往「APIs & Services」(API 和服務) 資訊主頁。

    前往 API 和服務頁面

  2. 選取您要用來存取 API 的專案。

  3. 按一下 [Add APIs and Services] (新增 API 和服務) 按鈕。

    新增 API 和服務

  4. 搜尋「Profiler API」

  5. 選取搜尋結果中的 [Stackdriver Profiler API]

  6. 如果畫面顯示 [API enabled] (API 已啟用),代表 API 已啟用。如果未顯示,請按一下 [Enable] (啟用) 按鈕。

安裝 Profiler 代理程式

Compute Engine

  1. 為 Profiler 代理程式建立安裝目錄,例如 /opt/cprof

     sudo mkdir -p /opt/cprof

  2. storage.googleapis.com 存放區下載代理程式封存,然後將封存解壓縮到安裝目錄:

    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | sudo tar xzv -C /opt/cprof

GKE

修改 Dockerfile,以便為 Profiler 代理程式建立安裝目錄,然後下載代理程式封存,再將封存解壓縮到安裝目錄:

RUN mkdir -p /opt/cprof && \
  wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
  | tar xzv -C /opt/cprof

彈性環境

使用 Google Java 8 執行階段基本映像檔或 Java 9/Jetty 9 執行階段基本映像檔時,Profiler 代理程式已預先安裝,因此您不需要採取其他步驟來安裝代理程式。

若是任何其他基本映像檔,則需要安裝代理程式。例如,以下 Dockerfile 包含使用 openjdk:11-slim 映像檔和安裝 Profiler 代理程式的指示,而且其中定義了啟動應用程式時要使用的預設參數:

FROM openjdk:11-slim

COPY . .
RUN  apt-get update \
     && apt-get install wget \
     && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /opt/cprof && \
    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | tar xzv -C /opt/cprof

CMD ["java", "-agentpath:/opt/cprof/profiler_java_agent.so=[OPTION1],[OPTION2]", "-jar", "PATH/TO/YOUR/JARFILE"]

如要在 App Engine 彈性環境中使用這個 Dockerfile,您必須執行下列操作:

  • [OPTION1][OPTION2] 改為應用程式所需的代理程式設定值,並將 PATH/TO/YOUR/JARFILE 改為您的 jar 檔案路徑。
  • Dockerfile 放在與 app.yaml 檔案相同的目錄中。
  • 修改 app.yaml 檔案以指定自訂的執行階段

標準環境

使用 Google Java 8 執行階段環境Java 11 執行階段環境 (Beta 版) 時,Profiler 代理程式已預先安裝,因此您不需要採取其他步驟來安裝代理程式。

GCP 以外的環境

  1. 為 Profiler 代理程式建立安裝目錄,例如 /opt/cprof

     sudo mkdir -p /opt/cprof

  2. storage.googleapis.com 存放區下載代理程式封存,然後將封存解壓縮到安裝目錄:

    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | sudo tar xzv -C /opt/cprof

載入 Profiler 代理程式

如要剖析應用程式,請按照程式正常執行方式啟動 Java,不過要指定 agent-configuration 選項;您要指定代理程式的程式庫路徑,之後即可將選項傳送到該程式庫。

如果是在 App Engine 標準環境,系統會自動載入並設定代理程式。如要進一步瞭解如何設定及啟動程式,請直接跳到「啟動您的程式」一節。

代理程式設定

如要設定剖析代理程式,請在啟動應用程式時加入 -agentpath 標記:

 -agentpath:[INSTALL_DIR]/profiler_java_agent.so=[OPTION1],[OPTION2],[OPTION3]

在這個運算式中,[INSTALL_DIR] 是剖析代理程式的路徑,而 [OPTION1][OPTION2][OPTION3] 是代理程式設定選項。例如,如果您在上一個運算式中將 [OPTION1] 改為 -cprof_service=myapp,便會將服務名稱設為 myapp。選項數量或其順序並無限制。下表列出了支援的設定選項:

代理程式選項 說明
-cprof_service 如果您的應用程式不是在 App Engine 上執行,您就必須使用這個設定選項來設定服務名稱。如要瞭解服務名稱限制,請參閱服務名稱和版本引數一節。
-cprof_service_version 如果您希望能夠根據服務版本使用 Profiler UI 來分析剖析資料,請使用這個選項設定版本。如要瞭解版本限制,請參閱服務名稱和版本引數一節。
-cprof_project_id 在 GCP 以外的環境執行時,請使用這個選項來指定您的 GCP 專案 ID。詳情請參閱剖析在 GCP 以外環境執行的應用程式的相關說明。
-cprof_zone_name 當您的應用程式在 GCP 上執行時,剖析代理程式會透過與 Compute Engine 中繼資料服務通訊來判斷區域。如果剖析代理程式無法與中繼資料服務通訊,您就需要使用這個選項。
-cprof_gce_metadata_server_retry_count
-cprof_gce_metadata_server_retry_sleep_sec
這兩個選項一起定義了 Profiler 代理程式在與 Compute Engine 中繼資料服務通訊時使用的重試政策,代理程式是透過該通訊來收集您的 GCP 專案 ID 和區域資訊。

預設政策是最多重試 3 次,並在兩次嘗試之間等待 1 秒鐘。這個政策已足以滿足大多數設定的需求。
-cprof_cpu_use_per_thread_timers 如要取得最準確的 CPU 作業時間剖析資料,請將這個選項設為 true。使用這個選項將會增加每個執行緒的負擔。

預設值是 false。
-cprof_force_debug_non_safepoints 根據預設,除了為所有安全點產生偵錯資訊之外,剖析代理程式也會強制 JVM 為所有 Just-In-Time (JIT) 產生的程式碼產生偵錯資訊。如此將可針對 CPU 作業時間和堆積剖析資料產生最準確的函式和行層級位置資訊,代價則是會產生額外的代理程式負擔。您可以將這個選項設為 false,藉此停止產生 JIT 程式碼的偵錯資訊。

預設值為 true。
-cprof_wall_num_threads_cutoff 根據預設,如果應用程式中的執行緒總數超過 4096 個,系統就不會收集實際時間剖析資料。這個限制可確保在剖析資料收集期間,周遊執行緒堆疊的成本是最低的。如果您的服務通常有 4096 個以上的執行緒,而且您想要以額外的負擔為代價來收集剖析資料,請使用這個標記來提高上限。

預設限制為 4096 個執行緒。
-cprof_enable_heap_sampling 如要針對 Java 11 或更新版本啟用堆積剖析功能,請
-cprof_enable_heap_sampling 設為 true。Java 10 和更舊的版本不支援堆積剖析功能。

堆積剖析功能預設為停用。

根據預設,啟用堆積剖析功能時,系統會將取樣間隔設為 512 KiB。對於大多數應用程式而言,這個間隔已經足夠,而且對應用程式產生的負擔會低於 0.5%。系統支援 256 KiB (262144) 到 1024 KiB (1048576) 的取樣間隔。舉例來說,如要將取樣間隔設為 256 KiB (使取樣率變成兩倍),請新增以下代理程式選項:

-cprof_heap_sampling_interval=262144
同樣地,如要將取樣間隔設為 1024 KiB (使取樣率減半),請新增以下代理程式選項:

-cprof_heap_sampling_interval=1048576

服務名稱和版本引數

載入 Profiler 代理程式時,您可指定 service-name 引數及 service-version 引數 (選用) 來加以設定。

「service name」(服務名稱) 可讓 Profiler 收集有關這項服務的所有備用資源剖析資料。分析器服務會針對每個服務名稱的各個版本及區域組合,確保平均每分鐘一個剖析作業的收集頻率。

舉例來說,如果您有一個服務,共有兩個版本在三個區域的備用資源執行,則分析器會為這個服務建立平均每分鐘 6 個剖析作業。

如果您為備用資源使用不同的服務名稱,系統剖析服務的頻率就會比平常更高,相對地負擔也會更大。

選取服務名稱時:

  • 選擇的名稱要能清楚代表應用程式架構中的服務。如果您只執行單一服務或應用程式,服務名稱的選擇就不那麼重要;但如果應用程式是以一組微服務的形式執行,建議就應選擇適當的服務名稱。

  • 請勿在 service-name 字串中使用任何 process-specific 值 (例如 ID)。

  • service-name 字串必須符合這個規則運算式:

    ^[a-z]([-a-z0-9_.]{0,253}[a-z0-9])?$

使用靜態字串 (如 imageproc-service) 做為服務名稱就是不錯的做法。

「service version」(服務版本) 則為選填項目。如果您指定服務版本,Profiler 可從多個執行個體匯總剖析資訊並正確顯示;這項引數可用來標記服務部署時的不同版本。Profiler UI 可讓您按照服務版本篩選資料,這樣一來,您就能比較新舊版程式碼的運作效能。

service-version 引數的值是任意形式的字串,不過這個引數的值看起來通常和版本號碼類似,例如 1.0.02.1.2

啟動程式

Compute Engine

按照程式正常執行方式來啟動 Java,並且新增 agent-configuration 選項:

java \
    -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myservice,-cprof_service_version=1.0.0 \
    [JAVA OPTIONS] -jar PATH/TO/YOUR/JARFILE [PROGRAM OPTIONS]

GKE

將服務容器 Dockerfile 修改為按照程式正常執行方式來啟動 Java,並且新增 agent-configuration 選項:

CMD ["java", \
    "-agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myservice,-cprof_service_version=1.0.0", \
    "-javaopt1=val1", "-javaopt2=val2", "-jar", "PATH/TO/YOUR/JARFILE", \
    "-programopt1=val1", "-programopt2=val2"]

彈性環境

修改 app.yaml 設定檔以設定 PROFILER_ENABLE 環境變數,然後再按照正常方式啟動程式:

env_variables:
   PROFILER_ENABLE: true

詳情請參閱定義環境變數一節。

標準環境

app.yamlappengine-web.xml 設定檔修改為包含 GAE_PROFILER_MODE 環境變數,以指示 Profiler 收集 CPU 作業時間和堆積剖析資料,頻率為針對同一個部署項目的所有執行個體平均每分鐘收集一次:

app.yaml:

env_variables:
   GAE_PROFILER_MODE: cpu,heap

appengine-web.xml:

  <env-variables>
    <env-var name="GAE_PROFILER_MODE" value="cpu,heap" />
  </env-variables>

然後再按照正常方式啟動程式。

詳情請參閱定義環境變數一節。

代理程式記錄

剖析代理程式可以報告 App Engine 彈性環境、Compute Engine 和 GKE 的記錄資訊。剖析代理程式支援以下記錄層級:

  • 0:記錄所有訊息。這是預設的記錄層級。
  • 1:記錄警告、錯誤和嚴重錯誤訊息。
  • 2:記錄錯誤和嚴重錯誤訊息。
  • 3:僅記錄嚴重錯誤訊息並停止應用程式。

如要使用預設的記錄層級將標準錯誤寫入記錄,請將 -logtostderr 附加至 -agentpath 設定。

如要將記錄層級設為僅記錄錯誤和嚴重錯誤訊息,請將 -minloglevel=2 附加至 -agentpath 設定。

舉例來說,如要啟用涵蓋錯誤和嚴重錯誤訊息到標準錯誤之間各層級的記錄功能,請將 -logtostderr‑minloglevel=2 附加至 -agentpath 設定:

 java -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myapp,-logtostderr,-minloglevel=2 -jar myApp.jar

後續步驟

如要進一步瞭解 Profiler 圖表和控制項,請參閱使用 Stackdriver Profiler 介面一文。如要瞭解進階資訊,請參考以下主題:

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Stackdriver Profiler