通過配置通用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: 4Gi
JVM配置
按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