歡迎訪問陳同學博客原文
隨着微服務的普及,許多企業踏上微服務之旅。
微服務化後,應用數量可能高一個數量級。一般企業,以前三五個應用能支撐業務,微服務化之後應用數量可能多達幾十個。每個微服務往往獨立部署,內存的消耗自然也高居不下,以前兩臺8核16G機器指不定就能跑起來,現兩臺16核64G還不一定夠用,同時由於多套環境的存在加上容器編排工具(如K8s)所需的資源,硬件資源的投入自然是成倍增加。
在 Web 應用開發中,爲了降低內存消耗,你是否嘗試過:
- 去除不必要的組件,減少代碼體積
- 更換 Web 容器,如將 Tomcat 更換爲Undertow
- 優化Docker基礎鏡像,減少鏡像體積
這些效果往往不是很理想。本篇介紹 OpenJ9 JVM,通過將 HotSpot 更換爲 OpenJ9,內存佔用能降低至少 60%,而啓動時間也能快 40% 以上,效果立竿見影。
OpenJ9 簡介
OpenJ9 的前身是IBM的 J9 Java 虛擬機,主要服務於IBM企業級軟件產品,是一款高性能的JVM。
2017年9月,IBM 將 J9 JVM 捐獻給 Eclipse 基金會,並更名 Eclipse OpenJ9,開啓開源之旅。
OpenJ9 擅長於內存管理,同時針對容器化做了很多工作,按官方說法是: more container-aware 。
下面摘自 OpenJ9 的 Release History,選擇了部分內容,可快速一覽:
-
2017.11 支持使用 OpenJDK8 構建 OpenJ9
-
2018.3 發佈 0.8.0:OpenJ9 開始支持各平臺(Mac、Linux、Windows等) 的 OpenJDK 8,宣佈在JDK8中,比HotSpot 42% faster startup and a footprint at least 60% smaller
-
2018.8 發佈 0.9.0:支持 OpenJDK 10;對Docker容器支持更友好;在運行一些Eclipse性能測試時,比HotSpot JVM快 43%,少用42%的內存.
-
2018.10 發佈 0.10.0:支持 OpenJDK 11,開始適配 HotSpot JVM的一些參數配置
-
2018.10 發佈 0.11.0:改善AOT性能、針對運行在容器中的應用內存優化、 “pause-less” GC mode for response-time sensitive, large heap applications
-
2019.2 發佈 0.12.1 :提示RSA算法加密性能;性能進一步提升
-
2019.3 發佈 0.13.0:支持OpenJDK 12; 支持jps命令;支持將Java dump 文件寫入STDOUT/STDERR
官方性能報告
下面是 OpenJ9官方的基準測試結果(完整報告),包含啓動時間、響應時間、吞吐量等指標。
66% smaller footprint after startup
由於減少內存佔用的重要性,OpenJ9 對雲負載(cloud wordloads)做了深度優化,在應用啓動後,佔用內存比HotSpot 約少 66%。
[外鏈圖片轉存失敗(img-KdaSxq7J-1563716139545)(https://imgcdn.chenyongjun.vip/2019/07/20/2.png)]
63% smaller footprint during ramp up
應用負載增加時,內存都會驟增。但狀態穩定後,使用 OpenJ9 的OpenJDK 8 比使用 HotSpot 的 OpenJDK 8 減少了約 63% 的物理內存。
42% faster startup time
Shared classes 和 Ahead-of-Time(AOT) 技術的應用顯著減少了應用啓動時間。通過使用 -Xquickstart 參數(啓用AOT),啓動時間可以減少高達42%。
Comparable throughput
在做吞吐量對比時,二者峯值吞吐量差不多,但使用OpenJ9 的 OpenJDK 8 大約快1分鐘達到峯值。
[外鏈圖片轉存失敗(img-bGM6xabN-1563716139548)(https://imgcdn.chenyongjun.vip/2019/07/20/5.png)]
Faster ramp-up time in the cloud
在雲環境下,虛擬化技術被廣泛使用,一臺大的機器經常被切割成若干小的虛擬機,這些虛擬機往往做了資源限制。OpenJ9 在單核CPU上用了8.5分鐘達到峯值吞吐量,而 HotSpot用了30分鐘。對於在資源受限的環境下(如雲環境)跑 short-lived VMs,能夠更快的完成更多工作就顯得更爲重要。
資源受限的一大副作用就是 Java應用花費更長的啓動時間(受JIT影響)。
筆者注:內存限制時,應用甚至會無法啓動,導致不斷重啓。
[外鏈圖片轉存失敗(img-UuhTWTj8-1563716139548)(https://imgcdn.chenyongjun.vip/2019/07/20/6.png)]
自己動手簡單測試
創建一個 Spring Boot Web 應用並打成jar包,分別使用 HotSpot、OpenJ9 虛擬機的 Open JDK8 結合Docker來做測試。
基於OpenJ9的Dockerfile
FROM adoptopenjdk/openjdk8-openj9:alpine-slim
COPY target/app.jar /app.jar
ENTRYPOINT java $JAVA_OPTS -Xshareclasses -Xquickstart -jar /app.jar
基於HotSpot的Dockerfile
FROM openjdk:8u181-jre-slim-stretch
COPY target/app.jar /app.jar
ENTRYPOINT java $JAVA_OPTS -jar /app.jar
啓動容器後,docker stats openj9 hotspot
查看容器資源使用情況如下:
[外鏈圖片轉存失敗(img-maQWAh0y-1563716139548)(https://imgcdn.chenyongjun.vip/2019/07/20/1.png)]
OpenJ9 是 50.89M;HotSpot 是235.7M,差異非常大。
下面是我們測試環境中的一個普通應用(使用Docker運行)的測試結果。
基於 Open JDK8 (HotSpot) 時內存消耗穩定在 1G左右。
[外鏈圖片轉存失敗(img-VtdmeruJ-1563716139549)(https://imgcdn.chenyongjun.vip/2019/07/21/2.png)]
基於 OpenJDK8(OpenJ9)時內存消耗穩定在 300M左右。
[外鏈圖片轉存失敗(img-4Bg2ehoc-1563716139549)(https://imgcdn.chenyongjun.vip/2019/07/21/3.png)]
切換到 OpenJ9 便利嗎
如果使用Docker,直接更換基礎鏡像即可,容器場景下更能發揮 OpenJ9 的作用。
如果JDK直接安裝在服務器上,可以直接在 AdoptOpenJDK 上下載相應的介質。
對於 JVM Options,可以參考做一些調整。
對開發人員的影響
大家一般接觸的都是HotSpot VM,且對於其理論、JVM參數、命令行工具甚至性能調優等相對比較熟悉,這塊資料也比較豐富。
OpenJ9 以前更多的是支持IBM企業級的商業產品,大家瞭解相對較少,連日用命令行工具暫時都只提供了jps、jstack,不過可以使用像阿里 arthas 這類Java應用診斷工具,效果也是一樣的。
對於小企業來說,JVM一般不是瓶頸,而更換JVM所帶來的IT成本投入減少確是實實在在的,尤其是對於初創團隊,自然是能省則省。
OpenJ9 相關資料
歡迎關注公衆號 [陳一樂],一起學習,一起成長
[外鏈圖片轉存失敗(img-yXDhgtKw-1563716139549)(https://media.chenyongjun.vip/2018/06/17/e0c3896def584a1ebf4fd85c082b6b3d.jpg)]