「龍井」開箱評測 |Alibaba Dragonwell 新手上路指南


做者|阿里雲智能事業羣 高級技術專家 陸傳勝java

阿里巴巴有着最豐富的 Java 應用場景,覆蓋電商,金融,物流等衆多領域,是世界上最大的 Java 用戶之一。 2019 年 3 月 21 日,阿里巴巴在北京阿里雲峯會上正式宣佈開源了 Alibaba Dragonwell 8 產品,並創建了 Alibaba Dragonwell 社區來爲全球 Java 用戶,特別是中文社區的 Java 用戶提供長期支持的 JDK 產品。自宣佈開源以來,Alibaba Dragonwell 8 受到了國內外 Java 開發者的關注,今天這篇文章就來詳解 Alibaba Dragonwell8 的快速安裝和使用,同時列出了參與社區建設的幾種方式,指望爲那些即將安裝及使用 Alibaba Dragonwell 8 的開發者提供參考。git

Alibaba Dragonwell 8 介紹

Alibaba Dragonwell 8 是一款免費的 OpenJDK 發行版。它提供長期支持,包括性能加強和安全修復。Alibaba Dragonwell 8 目前支持 X86-64/Linux 平臺,在數據中心大規模 Java 應用部署狀況下, 能夠大幅度提升穩定性、效率以及性能。Alibaba Dragonwell 8 是 OpenJDK 的下游(friendly fork),使用了和 OpenJDK 同樣的 licensing。Alibaba Dragonwell 8 與 Java SE 標準兼容,用戶可使用 Alibaba Dragonwell 8 開發和運行 Java 應用程序。這次開源的 Alibaba Dragonwell 8 是阿里巴巴內部 OpenJDK 定製版 AJDK 的開源版本, AJDK 爲在線電商,金融,物流作告終合業務場景的優化,運行在超大規模的,100,000+ 服務器的阿里巴巴數據中心。github

安裝 Alibaba Dragonwell 8

目前 Alibaba Dragonwell 8 只支持 Linux x86-64 平臺,而且提供了二進制的預編譯 JDK 包,您能夠經過下面的簡單兩步安裝 Alibaba Dragonwell 8。web

  • 從 Github 上面 Alibaba Dragonwell 8 項目的下載頁面下載預編譯的二進制 JDK 包。
    下載頁面連接 github.com/alibaba/dra…
  • 將下載下來的 tar 包解壓到目標安裝目錄便可。

安裝完畢後,只須要將應用引用 的 JAVA_HOME 指向 Alibaba Dragonwell 8 的安裝目錄就可使用了。咱們以Tomcat8.5.39 版本爲例,爲了讓 Tomcat 運行在 Alibaba Dragonwell 8上面,只須要在啓動Tomcat時使用以下命令:算法

JAVA_HOME=/path/to/dragonwell8/installation  sh tomcat/bin/catalina.sh start
複製代碼

爲了確認是運行在 Alibaba Dragonwell 8上面,能夠進一步經過給 java 命令添加 -showversion 參數來打印 JDK 版本信息加以判斷。apache

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-showversion" sh tomcat/bin/catalina.sh start
複製代碼

啓動完畢後在 tomcat/logs/catalina.out 文件的開頭,能夠看到 Alibaba Dragonwell 8 的版本信息bootstrap


使用 Alibaba Dragonwell 8 專有特性

在 8.0-preview 這個版本中, Alibaba Dragonwell 8 提供了兩個在阿里巴巴的生產環境中進行過普遍驗證的特性:JWarmUp 和 Java Flight Recorder。這兩個特性都已經在上游 OpenJDK 社區提交了 JEP 或 patch,在上游合併完成以前,咱們但願讓 Alibaba Dragonwell 8 的用戶能夠提早使用到這兩個特性。數組

JWarmUp 快速預熱 Java 應用

OpenJDK 使用了 JIT(Just-in-time) 即時編譯技術,能夠動態的把 Java 字節碼編譯成高度優化過機器碼,提升執行效率,但在編譯以前,Java 代碼是以相對低效的解釋器模式執行的。tomcat

在應用啓動完成後、業務流量剛進來的短期內,容易出現的情況是大量 Java 方法開始被 JIT 編譯,同時業務請求被較慢的解釋器模式執行,最終的結果就是系統負載飆高,可能致使不少用戶請求超時。爲了解決這個問題,以前的不少作法是使用模擬流量來提早預熱應用,JWarmUp 特性提供了一個新的選擇,就是利用 Java 虛擬機前一次執行編譯得記錄來預熱本次應用的執行。安全

JWarmUp 的原理以下圖所示:


一個典型的應用場景是當應用須要發佈新版本的時候,

  • 首先 JWarmUp 在 Beta 環境(或者有着和生產環境相似流量的其餘場景)的單臺機器上短期執行 Java 應用,並記錄、收集這段時間裏面 JIT 編譯器所作動做的一些元數據。
  • 而後會把這些元數據複製到生產環境的每一臺包含了新版本代碼的機器/容器裏面。
  • 最後在生產環境機器中經過 JWarmUp 參數加載 beta 環境生成的元數據,來指導生產環境的機器在啓動應用的過程當中就完成 JIT 預熱。

這樣當用戶請求進入的時候,應用就會處於性能最高的峯值狀態。

收集預熱數據

還以 Tomcat 應用爲例,能夠添加下面的命令行參數來在 beta 環境中收集 JIT 編譯時生成的元數據,其中參數 -XX:CompilationWarmUpLogfile= 指定的就是生成的 JWarmUp 文件的路徑。

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:ReservedCodeCacheSize=512m -XX:CompilationWarmUpLogfile=$PWD/jwarmup.log -XX:+CompilationWarmUpRecording -XX:+CompilationWarmUp -XX:-TieredCompilation -XX:+DeoptimizeBeforeWarmUp -XX:CompilationWarmUpDeoptTime=30 -XX:+PrintCompilationWarmUpDetail" sh bin/catalina.sh start
複製代碼

生成以後能夠把這個文件經過 OSS、SFTP 等方式傳輸到生產環境的機器上。

使用記錄的數據來預熱 Java 應用

在生產環境的機器上,只須要使用下面的參數,就能夠利用以前的預熱數據來啓動一個新的 Tomcat 實例,其中參數 -XX:CompilationWarmUpLogfile= 制定的就是須要被加載的 JWarmUp 文件路徑,這個文件應該是上一步收集預熱數據時從 beta 環境複製過來的。

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:ReservedCodeCacheSize=512m -XX:CompilationWarmUpLogfile=$PWD/jwarmup.log -XX:+CompilationWarmUp -XX:-TieredCompilation -XX:+DeoptimizeBeforeWarmUp -XX:CompilationWarmUpDeoptTime=30 -XX:+PrintCompilationWarmUpDetail" sh bin/catalina.sh start
複製代碼

使用 Java Flight Recorder 分析 Java 應用性能

JFR(Java Flight Recorder)是 JVM 內置的基於事件的性能分析特性,這是 Oracle JDK7u4 版本開始提供的商業特性,2018 年的時候在 JDK11 上開源了這個特性,可是一直沒有針對 JDK8 版本的支持。

阿里巴巴和 RedHat、Azul、Amazon 等公司一塊兒合做嘗試把這個特性移植回 JDK8上,不過該 patch 暫時尚未合併回 OpenJDK8u倉庫,咱們在 Alibaba Dragonwell 8 中提供了 Alibaba 移植的 JFR 版本,用於幫助用戶提早獲取這方面的支持。

JFR 的用法很簡單,用戶使用命令行參數或者 jcmd 命令控制 HotSpot 輸出性能數據到文件中,而後就能使用開源的 jmc 工具在圖形界面中打開、分析生成的數據文件了。

使用 JFR 收集性能數據

在 Alibaba Dragonwell 8中,默認狀況下 JFR 特性是處於關閉的狀態,必須添加命令行參數 -XX:+EnableJFR 來容許使用 JFR 特性。 Alibaba Dragonwell 8 提供了不一樣的方式來使用 JFR 採集性能數據。

應用能夠能夠經過命令行參數指定 JFR 再啓動後立馬開始採集數據,這個對於診斷啓動階段的問題會頗有幫助。下面的示例命令會在 Java 進程的 JFR 模塊初始化後就開始收集 JFR 數據,持續一分鐘,而且把數據都輸出到名爲rec.jfr 的文件中。

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:+EnableJFR -XX:StartFlightRecording=duration=1m,filename=rec.jfr" sh bin/catalina.sh start
複製代碼

應用也能夠只添加 -XX:+EnableJFR ,而後經過 jcmd 命令在應用啓動後的任意時間點開始採集數據,這種狀況更加靈活可控,能夠知足隨時隨地進行分析的需求。
以 Tomcat 爲例,啓動 Tomcat 的命令能夠是:

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:+EnableJFR" sh bin/catalina.sh start
複製代碼

當須要收集數據進行分析時,只須要使用目標 Tomcat 進程的 PID 來執行 JFR 對應的 jcmd 命令便可。以 Tomcat 爲例,若是須要在指定時刻開始收集 10 秒的數據,那麼觸發的命令以下:

$ ps ax | grep tomcat
 77522 pts/18   Sl+    0:08 /home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/../j2sdk-image/bin/java -Djava.util.logging.config.file=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XX:+EnableJFR -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/bin/bootstrap.jar:/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/bin/tomcat-juli.jar -Dcatalina.base=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39 -Dcatalina.home=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39 -Djava.io.tmpdir=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/temp org.apache.catalina.startup.Bootstrap start
 98451 pts/22   S+     0:00 grep --color=auto tomcat

$ dragonwell8_home/bin/jcmd 77522 JFR.start duration=10s filename=$PWD/rec3.jfr
77522:
Started recording 3\. The result will be written to:

/home/my/workdir/rec3.jfr
複製代碼

10 秒以後能夠看到生成了 JFR 數據文件/home/my/workdir/rec3.jfr,使用 JMC 便可進行分析。

也能夠不指定收集數據的時間,直接啓動 JFR 收集,而且在須要的時候手動把全部生成的數據一次性 dump 到文件,

$ dragonwell8_home/bin/jcmd 2823 JFR.start filename=$PWD/rec4.jfr
2823:
Started recording 4\. No limit specified, using maxsize=250MB as default.

Use JFR.dump name=4 to copy recording data to file.

$ dragonwell8_home/bin/jcmd 2823 JFR.dump name=4 filename=rec4.jfr
2823:
Dumped recording "Recording-4", 332.7 kB written to:

/path/to/my/workdir/rec4.jfr
複製代碼

使用 JMC 分析性能

JFR 記錄 Java 應用性能數據的輸出是一個二進制的文件,咱們藉助於 JMC(Java Mission Control) 工具能夠在圖形化界面裏面分析具體的性能數據。這個工具是開源產品,沒有包括在 Alibaba Dragonwell 8裏面,須要到 OpenJDK 的官方網站下載使用,jdk.java.net/jmc/

請注意, Alibaba Dragonwell8 生成的JFR數據文件須要 7.0 或更高版本的 JMC 工具來分析。

打開 JMC 後,能夠點擊左側的詳細類別來詳細分析採樣時間段內發生的各類事件。


診斷調試支持

Alibaba Dragonwell 8 還內置一些方便的診斷特性,主要包括

大對象分配報警

能夠經過新的 JVM 參數"-XX:ArrayAllocationWarningSize=",好比下面代碼中分配了比較大的數組

public static void main(String[] args) {
    doAlloc(32 * 1024 * 1024 + 1);
}
private static Object doAlloc(int size) {
    return new byte[size];
}
複製代碼

執行時若是添加 ArrayAllocationWarningSize 選項就會打印出分配該數組時的 Java 堆棧


詳細的 ParNew GC 日誌支持

Alibaba Dragonwell 8 默認使用了 CMS (Concurrent Mark Sweep) 算法,新生代使用了 ParNew 算法,因此內置兩個針對 ParNew GC 日誌的加強

  • 能夠經過 jinfo 工具設置 PrintYoungGenHistoAfterParNewGC 選項來在下一次 Young GC 結束的時候打印新生代的對象類型直方圖。命令以下
jinfo -flag +PrintYoungGenHistoAfterParNewGC <pid>
複製代碼

打印完成後,這個選項會被重置回 false 狀態,防止過多的輸出,一個典型的輸出例子以下:


  • 能夠經過-XX:+PrintGCRootsTraceTime 來打印處理每一類 GC 根集所花費的詳細 CPU 時間,輸出示例以下:

精簡版 HeapDump 支持

Alibaba Dragonwell 8 的 jmap 工具支持一個新的 dump 選項「mini」能夠在作 heapdump 的時候跳過全部的原始類型數組的內容,從而大大減少生成的 heapdump 文件大小,這對於只須要排查類型、對象關係的場景會比較有幫助。

示例命令以下:



本文做者:jessie筱姜

原文連接

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索