問題描述
在實際開發過程中, 將 springboot 項目打成 Docker 鏡像部署在 kubernetes 集羣中, 並啓動容器實例, 打開日誌, 發現很久才能刷一條日誌, 並且項目啓動超過 10 分鐘!!!
如下爲服務 yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-${SVC_NAME}
namespace: ${NAMESPACE}
spec:
replicas: 2
selector:
matchLabels:
app: ${SVC_NAME}
template:
metadata:
labels:
app: ${SVC_NAME}
spec:
containers:
- name: container-${SVC_NAME}
image: ${IMAGE_NAME}
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 3G
解決方案
排查的過程就不過多描述了, 究其原因, 是啓動實例時, 對實例 CPU 資源限制所導致的, 也就是 yaml 文件中 resources.limits.cpu=100m
所致, 增加分配給服務的 CPU, 可相應縮短服務的啓動時間, 在我的環境中, 分配 1core, 對服務啓動速度的提升任然收效甚微, 所以我索性把 CPU 的資源限制去掉了 , 原本啓動要 1000s+, 現在的啓動速度爲 10s+.resources.limits.cpu=100m
爲什麼 CPU 資源對服務啓動的影響如此之大:
jvm在啓動的時候會裝載並連接所有除反射以外的類,而class文件是二進制的文件,需要從磁盤加載到內存然後解析,這種解析是很耗費cpu的,那麼class文件越多,cpu耗費就越高
這裏列出幾種提升 springboot 服務啓動速度的方案
- 加cpu,效果十分明顯
- 去掉不必要的pom依賴,特別是大的jar,效果和jar大小直接相關
- 隨機數改成僞隨機數,/dev/random改成/dev/./urandom可能十分明顯,也能完全沒有效果
- 修改JVM參數,屏蔽字節碼校驗,效果不明顯
- 排除不必要的自動配置,效果不明顯
如有遇到相同情況的朋友可以參考批評指正, 另外如果有優化啓動的其他方案也歡迎留言.