微服務中使用 OpenJ9 JVM 內存佔用降60%(相對HotSpot)

歡迎訪問陳同學博客原文

隨着微服務的普及,許多企業踏上微服務之旅。

微服務化後,應用數量可能高一個數量級。一般企業,以前三五個應用能支撐業務,微服務化之後應用數量可能多達幾十個。每個微服務往往獨立部署,內存的消耗自然也高居不下,以前兩臺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 classesAhead-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)]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章