將 Java 應用程式容器化
本文提供容器化 Java 應用程式的建議策略和設定概觀。
當您將 Java 應用程式容器化時,請仔細考慮容器可用的 CPU 時間。 然後考慮在記憶體總量和 Java 虛擬機的堆積大小方面,可以使用多少記憶體。 在容器化環境中,應用程式可以存取所有處理器,因此能夠平行執行多個線程。 不過,容器通常會套用CPU配額,以節流存取CPU。
JVM 有啟發學習法,可根據 CPU 配額來判斷「可用的處理器」數目,這可能會大幅影響 Java 應用程式的效能。 配置給容器本身的記憶體,以及 JVM 堆積區域的大小與處理器一樣重要。 這些因素將決定垃圾收集行程 (GC) 的行為,以及系統的整體效能。
容器化新的應用程式
當您為新的應用程式容器化 Java 工作負載時,在考慮記憶體時,必須考慮兩件事:
- 配置給容器本身的記憶體。
- Java 進程可用的記憶體數量。
瞭解 JVM 預設程式
應用程式需要起點和設定。 JVM 具有預設程式設計工具,其具有預先定義的值,這些值是以系統中可用的處理器數目和記憶體數量為基礎。 當 JVM 啟動時,不使用特定的啟動旗標或參數,就會使用下表中顯示的預設值。
下表顯示用於可用資源的預設 GC:
可用的資源 | 預設 GC |
---|---|
任意數目的處理器 最多 1791 MB 的記憶體 |
SerialGC |
2 個以上的處理器 1792 MB 或更多記憶體 |
G1GC |
下表顯示預設的最大堆積大小,視 JVM 執行所在的環境中可用的記憶體數量而定:
可用的記憶體 | 預設最大堆積大小 |
---|---|
最多 256 MB | 50% 的可用記憶體 |
256 MB 到 512 MB | ~127MB |
超過 512 MB | 25% 的可用記憶體 |
預設 的初始堆積大小 是可用記憶體的 1/64。
這些值適用於 OpenJDK 11 和更新版本,以及大多數散發套件的有效值,包括 Microsoft Build of OpenJDK、Azul Zulu、Eclipse Temurin、Oracle OpenJDK 等等。
判斷容器記憶體
根據應用程式的需求及其獨特的使用模式,挑選最適合您工作負載的容器記憶體數量。 例如,如果您的應用程式建立大型物件圖形,則可能需要比具有許多小型物件圖形的應用程式所需的記憶體更多。
提示
如果您不知道要配置多少記憶體,良好的起點是 4 GB。
判斷 JVM 堆積記憶體
當您配置 JVM 堆積記憶體時,請注意 JVM 需要的記憶體不僅僅是 JVM 堆積所使用的記憶體。 當您設定 JVM 堆積記憶體上限時,它不應該等於容器記憶體的數量,因為這會導致容器記憶體不足(OOM)錯誤和容器當機。
提示
為 JVM 堆積配置 75% 的容器記憶體。
在 OpenJDK 11 和更新版本上,您可以透過下列方式設定 JVM 堆積大小:
描述 | 旗標 | 範例 |
---|---|---|
固定值 | -Xmx |
-Xmx4g |
動態值 | -XX:MaxRAMPercentage |
-XX:MaxRAMPercentage=75 |
最小/初始堆積大小
如果環境保證保留給 JVM 實例的特定內存量,例如在容器中,您應該將堆積大小下限或初始堆積大小設定為與堆積大小上限相同的大小。 此設定會向 JVM 指出它不應該執行將記憶體釋放至 OS 的工作。
若要設定最小堆積大小,請使用 -Xms
絕對數量或 -XX:InitialRAMPercentage
百分比數量。
重要
旗標-XX:MinRAMPercentage
,儘管名稱建議,但用於設定系統中最多可用 RAM 256 MB 的系統的預設 RAM 百分比上限。
判斷要使用的 GC
先前,您已決定要開始使用的 JVM 堆積記憶體數量。 下一個步驟是選擇您的 GC。 您擁有的最大 JVM 堆積記憶體數量通常是選擇 GC 的因素。 下表描述每個 GC 的特性。
因素 | SerialGC | ParallelGC | G1GC | ZGC | 謝南多亞GC |
---|---|---|---|---|---|
核心數目 | 1 | 2 | 2 | 2 | 2 |
多線程 | No | .是 | .是 | .是 | Yes |
Java 堆積大小 | <4 GB | <4 GB | >4 GB | >4 GB | >4 GB |
暫停 | Yes | .是 | Yes | 是 (<1 毫秒) | 是 (<10 毫秒) |
負荷 | 最小 | 最小 | 中等 | 中等 | 中等 |
尾延遲效果 | 高 | 高 | 高 | 低 | 中等 |
JDK 版本 | 全部 | 全部 | JDK 8+ | JDK 17+ | JDK 11+ |
適用對象 | 單一核心小型堆積 | 具有任何堆積大小的多核心小型堆積或批次工作負載 | 在中型到大型堆積中回應 (request-response/DB 互動) | 在中型到大型堆積中回應 (request-response/DB 互動) | 在中型到大型堆積中回應 (request-response/DB 互動) |
提示
針對大部分一般用途的微服務應用程式,請從平行 GC 開始。
判斷需要多少 CPU 核心
對於 SerialGC 以外的任何 GC,我們建議在 Kubernetes 上至少cpu_limit兩個以上的 vCPU 核心2000m
。 不建議在容器化環境中選取小於 1 個 vCPU 核心的任何專案。
提示
如果您不知道要從多少核心開始,不錯的選擇是 2 個 vCPU 核心。
挑選起點
建議您從 Kubernetes、OpenShift、Azure Spring Apps、Azure Container Apps 和 Azure App 服務 等容器協調流程環境中的兩個複本或實例開始。 下表摘要說明新 Java 應用程式容器化的建議起點。
vCPU 核心 | 容器記憶體 | JVM 堆積大小 | GC | 複本 |
---|---|---|---|---|
2 | 4 GB | 75% | ParallelGC | 2 |
要使用的 JVM 參數如下: -XX:+UseParallelGC -XX:MaxRAMPercentage=75
容器化現有的 (內部部署) 應用程式
如果您的應用程式已在內部部署或雲端中的 VM 上執行,建議您從下列項目開始:
- 應用程式目前可存取的記憶體數量相同。
- 應用程式目前可用的CPU數目相同。
- 您目前使用的相同 JVM 參數。
如果無法使用 vCPU 核心和/或容器記憶體組合,請挑選最接近的 VCPU 核心和容器記憶體。
下一步
既然您已瞭解容器化 Java 應用程式的一般建議,請繼續進行下列文章,以建立容器化基準: