通過配置通用Java Virtual Machine(JVM)的記憶體回收機制(Garbage Collection Mechanism)和Just-In-Time(JIT)參數,能夠更好地在Java應用啟動過程中使用ACS的柔性變更配置能力。本文介紹和Java應用啟動加速相關的ParallelGCThreads、ConcGCThreads和CICompilerCount三個JVM參數的推薦配置方法。
背景介紹
Java應用在啟動階段需要經歷類載入、位元組碼編譯和最佳化的階段,這個階段對於一些複雜的應用而言,可能要持續幾分鐘甚至十幾分鐘的時間。通常在這個階段Java應用佔用了超過一半的資源執行非應用代碼的載入、編譯的邏輯。而在應用預熱完成進入穩定運行態後,這些資源會處於空閑狀態。因此您可以通過ACS的柔性算力變更配置能力,在Java應用啟動時提供更多的算力來加速應用啟動。
在JVM虛擬機器中普遍存在編譯線程、使用者進程和記憶體回收線程,這些線程會在Java應用啟動以及穩定啟動並執行不同階段,以不同的比例共同佔據整個Java應用的資源。 為了使Java應用能更好地發揮應用啟動加速的效益,同時保證Java穩態運行時的效能,需要根據業務自身的特徵,調整JVM參數配置從而合理地分配線程資源。

變更配置相關JVM參數推薦配置
下面將重點介紹和應用啟動加速相關的3個重要JVM參數:ParallelGCThreads、ConcGCThreads和CICompilerCount,以及它們的推薦配置參數。
假設使用者程式設定的實際CPU核心數是
JVM參數 | 參數說明 | 推薦配置參數 | |
| 並行GC的線程數。表示並行記憶體回收行程使用的線程數量。 | 若 若 | |
| 並發GC的線程數。這些線程與應用程式線程並發運行,以減少停頓時間,所以需要給業務線程保留足夠的線程數資源。 | 配置值計算方法 | |
| JIT編譯線程數。此數值與程式的執行效率相關。頻繁的JIT編譯可能會導致效能瓶頸,因此不合理的JIT編譯線程數會影響程式的執行效率。若配置過少的JIT線程數,因為解釋執行效率較低的原因,可能會導致方法執行慢並且佔用過高的CPU資源。 | 變更配置後CPU核心數( |
|
1 | 2 | ||
2 | 2 | ||
4 | 3 | ||
8 | 3 | ||
16 | 8 | ||
32 | 10 | ||
64 | 12 | ||
典型情境配置參考
編排配置
在一個典型Java應用建立執行個體時,通過柔性變更配置多分配1倍的CPU資源, 同時變更配置維持到應用Ready後足夠長時間(保證應用充分預熱),一般可以觀察到比較顯著的加速效果。 如果Java應用要載入的庫比較多,或者除了JVM自身編譯以及預熱外,應用有額外的耗時的初始化動作,變更配置的期間相對需要更長。
由於根據變更配置後的核心數配置的GC和JIT的線程數,在降配後會超出實際分配的CPU數,如果應用在啟動階段沒有完全預熱,而是在降配後預熱,在高負載的情況,可能會導致GC和JIT線程與應用爭搶CPU資源。針對此情況,應該讓應用在啟動階段升配的情況儘可能的完成應用的預熱。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-with-burst
name: spring-with-burst
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: spring-with-burst
minReadySeconds: 400 # 推薦配置略大於變更配置期間的值, 從而保證在變更配置結束後,能夠檢驗執行個體的狀態
template:
metadata:
annotations:
alibabacloud.com/startup-cpu-burst-factor: '2' #設定啟動擴容倍數為2, 即初始1C會以2C啟動
alibabacloud.com/startup-cpu-burst-duration-seconds: "300" #預設的30s變更配置期間較短,大部分Java應用能在10分鐘內啟動完成,再加上5分鐘足夠完成預熱階段。建議根據應用的實際情況, 設定大於預設值的變更配置期間。
scaling.alibabacloud.com/enable-inplace-resource-resize: 'true' # 聲明開啟熱變更配置
labels:
alibabacloud.com/compute-class: general-purpose
alibabacloud.com/compute-qos: default
app: spring-with-burst
spec:
containers:
- image: 'registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/demo-java:java-with-metrics-v1'
imagePullPolicy: IfNotPresent
name: spring
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: 1
memory: 4Gi
requests:
cpu: 1
memory: 4GiJVM配置
按1倍升配的CPU配置, 可以參照如下的JVM參數配置:
原CPU核心數 | 變更配置後CPU核心數 | ParallelGCThreads | ConcGCThreads | CICompilerCount |
0.5 | 1 | 1 | 1 | 2 |
1 | 2 | 2 | 1 | 2 |
2 | 4 | 4 | 1 | 3 |
4 | 8 | 8 | 2 | 3 |
8 | 16 | 13 | 3 | 8 |
您可以在對應容器內通過以下Java命令檢查Java版本的預設線程配置(例如ParallelGCThreads):
java -XX:+PrintFlagsFinal -version | grep ParallelGCThreads以原CPU核心數為1,變更配置後CPU核心數為2的情境為例,如果Java預設的相關線程配置和推薦的配置差別較大,則可以修改Java應用的啟動命令如下:
java -XX:ParallelGCThreads=2 -XX:ConcGCThreads=1 -XX:CICompilerCount=2 -jar app.jar