在 Kubernetes 中手動錄製 Java Flight Recorder
此處說明如何在沒有其他工具可用的情況下,為容器化環境中的 Keycloak 建立 Java Flight Recorder 錄製。
概觀
Java Flight Recorder (JFR) 會記錄 Java 虛擬機的事件,包括可以組合成火焰圖並用於分析效能的執行緒傾印。在功能完善的設定中,使用 Cryostat 擷取效能指標提供了一種自動化的方式,而且不需要自訂 Keycloak 映像檔。如果沒有這樣的設定可用,請按照這些指示擷取 JFR。
這並未使用非同步分析,因為據我所知這在 OpenShift 內部不可用。因此,錄製將具有 Safepoint 偏差問題。請參閱在容器中分析 Java。 |
準備 Keycloak 映像檔
以下程序需要在容器中存在 jcmd
以啟動 Java Flight Recording,並需要 tar
以便能夠使用 kubectl cp
從容器中檢索錄製。
雖然較舊版本的 Keycloak 包含這些工具,但較新的 Keycloak 映像檔版本不包含它們,以使映像檔更小、更安全。因此,第一步是使用這些工具建立自訂 Keycloak 映像檔。有兩種方法可以做到這一點:從頭開始建立 Keycloak 映像檔,或使用必要的套件更新 Keycloak 映像檔。
從頭開始建立 Keycloak
如果您從 Keycloak 的主要儲存庫建立 Keycloak 的自訂發行版,請變更檔案 quarkus/container/Dockerfile
並交換行
RUN bash /tmp/ubi-null.sh java-17-openjdk-headless glibc-langpack-en
為
RUN bash /tmp/ubi-null.sh java-17-openjdk-devel tar glibc-langpack-en
然後按照在 Kubernetes 中部署使用自訂 Keycloak 映像檔中的說明建立映像檔。
將額外的 RPM 套件新增至映像檔
Keycloak 關於容器的文件包含一個關於如何新增套件的章節。若要新增兩個套件 java-17-openjdk-devel tar
,請使用如下的 Dockerfile
FROM registry.access.redhat.com/ubi9 AS ubi-micro-build
RUN mkdir -p /mnt/rootfs
RUN dnf install --installroot /mnt/rootfs java-17-openjdk-devel tar --releasever 9 --setopt install_weak_deps=false --nodocs -y; dnf --installroot /mnt/rootfs clean all
FROM quay.io/keycloak/keycloak
COPY --from=ubi-micro-build /mnt/rootfs /
然後按照在 Kubernetes 中部署使用自訂 Keycloak 映像檔中的說明使用映像檔。
更新 JVM 選項
從 Keycloak 23 開始,不再需要覆寫 -XX:FlightRecorderOptions=stackdepth JVM 選項,因為 Keycloak 預設使用 512。 |
Keycloak 在其調用中使用非常深的堆疊追蹤。為了能夠使用火焰圖,請新增以下 JVM 選項來增加堆疊幀的數量。
-XX:FlightRecorderOptions=stackdepth=512
當使用 Keycloak Operator 時,可以透過 Keycloak 的 CustomResource 將其傳遞至 Keycloak 映像檔,如下所示
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
spec:
unsupported:
podTemplate:
spec:
containers:
- env:
- name: JAVA_OPTS_APPEND
value: >
-XX:FlightRecorderOptions=stackdepth=512
如果您正在執行由 Operator 管理的 StatefulSet 或 Deployment,請考慮停止 Operator 並手動更新 StatefulSet 或 Deployment 以新增或擴充 Java 選項。
開始錄製
若要開始錄製,請在容器中發出命令
kubectl exec -n namespace pod -- jcmd 1 JFR.start duration=60s filename=/tmp/recording.jfr settings=/usr/lib/jvm/java/lib/jfr/profile.jfc
值 1
是 Java 程序的處理序 ID,它是所有基於 Quarkus 的 Keycloak 容器的預設值。對於基於 Wildfly 的發行版,這可能是不同的處理序 ID。使用不帶參數的 jcmd
來列出所有 Java 處理序 ID,以找到您要尋找的處理序 ID。
如果 Pod 中有多個容器正在執行,請新增 CLI 選項 -c container
。
profile.jfc
包含關於要擷取的內容的指示。profile.jfc
是 JVM 隨附的標準設定檔之一,代表「分析」:它收集大量資訊,並且應該收集幾分鐘的資訊。一分鐘的錄製將收集大約 5 MB 的資料,因此請尋找較短的時間跨度。根據需要調整它以收集您需要的資訊。
檢索錄製
若要檢索錄製,請發出以下命令
kubectl cp -n namespace keycloak pod:/tmp/recording.jfr recording.jfr --retries 999
如果 Pod 中有多個容器正在執行,請新增 CLI 選項 -c container
。
CLI 選項 --retries 999
有助於恢復大型檔案的下載,否則可能會失敗。
分析錄製
有關詳細資訊,請參閱分析 Java Flight Recorder 錄製。