今年 3 月份,阿里巴巴重磅開源 OpenJDK 長期支持版本 Alibaba Dragonwell 的消息,在很長一段時間內都是開發者的討論焦點,該項目在 Github 上的 Star 數迅速突破 1400。近日,Dragonwell JDK 8.0.0 正式發布 GA 版本,這意味着其已經具備在生產環境正式運行的能力。
2019 年 3 月,Dragonwell JDK正式開源,發布預覽 (Preview) 版本。近日,阿里巴巴重磅宣布 Dragonwell JDK 8.0.0-GA 正式發布,這意味着 Dragonwell JDK 已經完全具備在生產環境運行的能力。在過去三個月時間內,Dragonwell 收到了很多來自社區成員的反饋。那么,本次正式發布的 GA 版本加入了哪些新特性?對開發者而言意味着什么?
龍井 8.0.0-GA 的新變化
8.0.0-GA 的工作目的是為了讓 Dragonwell 盡快能夠在產品環境里使用。在這個版本里我們同步了 OpenJDK 上游社區 jdk8u212-b04 的最新更新,這也意味着我們同步了上游最新的安全更新和補丁。
除了同步上游,Dragonwell8 還修復了一些在阿里巴巴的 Java 場景下發現的一些非常重要的 Bug,並且經受了阿里巴巴內部場景的檢驗。同時我們也提供了一個默認的安全證書,這個證書我們會隨時更新和維護。
熟悉 Dragonwell 的小伙伴可能都知道,Dragonwell 和 OpenJDK 上游相比提供了一些專有的特性比如:JFR,JWarmUp 等。這些特性在阿里巴巴內部得到了廣泛應用,為阿里巴巴的 Java 業務的穩定運行立下了汗馬功勞,也可以說是 Dragonwell 的獨門武器。在 8.0.0-GA,我們也針對 JFR 特性做了一些修復和兼容性上的改進。所以喜歡 Dragonwell 新特性的的社區小伙伴們可以放心大膽的使用它們了。我們堅信,這些新特性不僅能夠阿里巴巴帶來價值,同時也能給社區的Java生態帶來價值。
8.0.0-GA 的發布具體的內容大家可以參考 github 的 release notes, 戳這里
龍井的新征程
介紹完龍井 8.0.0-GA 的新變化,很多小伙伴已經躍躍欲試了。別忙,在使用之前我們再多嘮兩句,作為龍井的家人,寶寶該如何成長,我們有着許多的想法,但龍井是社區的孩子,但我們也非常希望社區的小伙伴們能夠幫助它們變化成長。所以我們就一起談談龍井未來可能發生那些變化。
龍井的自從誕生開始,就吸引了社區的目光,尤其是 Dragonwell JDK 的一些新特性,幫助用戶在面臨業務挑戰時有了更多選擇。在今年 ISCA2019 Runtimes in the Cloud Tutorial 中,我們向社區和學術界匯報了 Dragonwell 在新特性上的工作進展,也得到了大家的積極響應。社區的反饋也是我們下一步工作的動力,希望小伙伴多給意見。這個 talk 的介紹在這里 http://www.cs.utah.edu/cloudruntimes/schedule.html#xiaoming ppt 從這里下載 http://www.cs.utah.edu/cloudruntimes/slides/xiaoming.pdf
有興趣的小伙伴可以看下。
Dragonwell 目前存在的幾個特性都是經過阿里巴巴龐大 Java 場景的檢驗,在穩定性上是非常可靠的。下面我們就來具體談談這幾個特性。
JWarmUp
JWarmUp 這個特性是為了解決阿里巴巴的雙 11 場景中搶購場景 Java 系統 Warmup 的痛點。以普通的 Java 應用舉例,JVM 需要經過解釋執行 (interpreter) 找到熱點,然后通過 JIT 編譯器來加速熱點方法的運行。對於高並發的場景,應用啟動之后會有很長的時間處於尋找熱點,編譯熱點的狀態,這時很多性能指標 (CPU 使用率, TPS 吞吐量, RT 響應時間)是不理想的。換句話,當 Java 應用啟動並提供服務之后,在相當長的時間內,處於一種 Warmup 的狀態,這時候雖然 Java 能夠對外提供服務,但服務的質量是比較差的,如果在這個階段用戶的並發比較高,那么就往往會造成服務質量的降級乃至服務崩潰。
為了優化這個過程,通常的工業實踐會在 Java 啟動后引入"預熱" (Warmup) 這個步驟,通過一些人為導入的數據來讓應用提前加熱,在預熱完成之前,用戶的請求通過網絡控制不讓它發送到 Java 進程,在預熱完成之后才打開流量限制讓 Java 真正提供服務。這個做法可以部分緩解上述問題,但是這個方案在很多場景下會有一些局限性,這是因為很多情況下,獲取一份高質量的預熱數據是很困難的。而預熱數據的正確性直接影響到預熱的效果,與實際情況相符的數據可以提高編譯的質量,如果不一致,有時反而會造成反面效果,比如一種常見的情況是預熱時會漏掉一些重要方法沒有被調用。更糟糕的情況是由於和實際情況不一致,導致 JVM “退優化”已編譯的方法,重新開始編譯,反而惡化了狀況。由此可見,如何准備預熱數據其實是一個挺復雜的問題,在實際運維中還沒有很好的解決方法。
Dragonwell 提出的 JWarmup 技術從 JVM 層面來解決這個痛點,基本原理是利用之前運行的情況找到熱點方法和 java class 信息,之后的 JVM 運行實例可以利用上次的信息來預熱,不需要通過人為數據來預熱。收集熱點的實例可以有多種選擇,例如在應用集群中選擇一個節點,也可以在發布過程中選擇一個 beta 發布的階段來收集。相比之前“人為數據”的方式,主要有這幾個優勢:
- 收集熱點的時候可以利用真實數據,達到更好的編譯效果。
- 加速預熱的過程。由於熱點方法可以在加載后直接編譯,節省了解釋執行,profiling 等過程。
這個功能在 specjvm2008 的基准測試中,對於某些測試用例,跑分會有明顯提高:
# 標准OpenJDK在specjvm2008的xml.validation測試用例上的跑分 Score on xml.validation: 268.07 ops/m # Dragonwell在specjvm2008的xml.validation測試用例上的跑分 Score on xml.validation: 294.95 ops/m
可以看出 Dragonwell 將 xml.validation 的跑分從 268.07 ops/m 提高到 294.95 ops/m,大概有10%的提高。
這個特性在阿里巴巴的雙 11 搶購場景中得到了大量的驗證,可以說是 Dragonwell 的秘密武器。目前我們也正在社區努力推進,希望通過 JEP 的方式,把這個功能推進到上游 OpenJDK 社區。畢竟好用的東西,不能只有我們自己有,大家要共同富裕才是王道。目前這個 JEP Draft 正在社區 review 的階段,小伙伴如果覺得這個特性好用的話,也可以 OpenJDK 社區的郵件列表里代表中國開發者為 Dragonwell 發聲。
JFR
JFR 全名是 Java Flight Recorder(Java 飛行記錄儀), 是 Dragonwell 的一個功能特性,當該功能被打開后,JVM 能夠以非常小的性能開銷記錄 Java 運行過程中產生的各種運行時數據。產生的 JFR 數據包含 JVM 運行時的各種微觀細節,可以被 JMC(Java Mission Control) 進行分析。JMC 是一個桌面應用程序,通過解析 JFR 數據,JMC 能夠高效快速的定位線上產品環境的各種故障。它能夠分析內存分配熱點,方法調用熱點,方法調用超時分析,內存泄漏,IO 活動,線程活動等各個方面,幫助 Java 用戶保證服務的穩定。
阿里巴巴日常開發過程中遇到的很多問題都是通過 JFR 得到解決的,可以說是 Java 故障診斷的一個利器。JFR 這個功能在 OpenJDK 11 以及以上的版本才有。在阿里巴巴的推動努力下,JFR 功能已經開始被 OpenJDK 社區接受,計划進 OpenJDK 8u 主線,目前社區的移植工作正在 incubator 分支緊張得進行當中,在不遠的將來,整個 OpenJDK 8 的下游生態都可以享受這個工作成果。
Dragonwell 作為 JFR 在 OpenJDK 8u 社區工作的參與方,會源源不斷的把 JFR 的最新工作成果及時引入 Dragonwell,Dragonwell 的用戶可以說有福了。另外,除了 JFR 社區現有的功能,Dragonwell 在 JFR 上也做了很多增強和創新,一方面我們會積極把這些 JFR 的新特性反饋給上游 OpenJDK 社區,另外,在推動上游的同時,Dragonwell 的用戶會天然的享有一些特別的福利:在上游社區接受這些特性之前,Dragonwell 會最先開源這些新功能。
神秘嘉賓: ElasticHeap
最后就要介紹下我們的神秘嘉賓 ElasticHeap 了。Dragonwell 會源源不斷地把阿里巴巴內部的一些創新特性反饋到社區,ElasticHeap 就是繼 JFR,JWarmUp 之后,Dragonwell 帶着滿滿的誠意計划開放的第三個新特性(進入下一個版本發布),OpenJDK 社區也是沒有的哦。
大家知道,Java 作為高級語言會帶有垃圾回收器,隨着程序的運行,Java 會把用戶配置的內存逐漸全部使用掉。即使這些 Java 進程后來變得比較空閑,不需要這么多資源了,那這些被占用掉的內存也不會歸還給操作系統,從資源利用的角度,這會帶來某種意義上的浪費。而 Dragonwell 的 ElasticHeap 就改變了這種情況,這是一個基於 G1 GC 的動態堆彈性伸縮的功能,可以有效節約 java 進程實際物理內存占用。Openjdk8 僅支持在 Full GC 時按照一定規則歸還物理內存。而 Dragonwell 的 ElasticHeap 提供了更敏捷有效的歸還內存的方式,有如下幾個特點:
1. 不依賴 Full GC 和其他 STW 暫停處理彈性堆伸縮,不增加額外 STW 開銷,不影響 Java 線程服務。
2. 支持多種模式。
a. 根據內存分配速度和 GC 壓力自適應調整堆大小(自動歸還內存)
b. 根據 jcmd/MXBean 命令主動式限制堆的大小(可整堆限制或分代限制)
下圖是阿里巴巴電商應用在雙 11 時使用 ElasticHeap GC 壓力自適應堆調整的應用的監控圖
- 圖中上半部分為 CPU 使用率,下半部分為物理內存使用率
- 雙 11 整點當服務流量進來時 (traffic peak starts),CPU 使用率大幅提升
- 同時開啟 ElasticHeap 堆內存自適應調整時,會配合 GC 壓力增大快速回漲堆內存;流量退去 CPU 利用率變小后,GC 壓力變小后,迅速的歸還物理內存
- 本例中,低流量時歸還物理內存約 20-30%
各位小伙伴們請期待吧,ElasticHeap 將在下個版本的發布中揭開神秘面紗。
安裝使用
目前 Alibaba Dragonwell 只支持 Linux x86-64 平台,開發者可通過如下步驟使用 Alibaba Dragonwell。
安裝 Alibaba Dragonwell
- 選項一:下載預編譯 Dragonwell 二進制包
- 從 Alibaba Dragonwell 的 Github 頁面下載二進制 tar 包,鏈接 https://github.com/alibaba/dragonwell8/releases
- 將下載下來的 tar 包解壓到目標安裝目錄即可
- 選項二:使用 YUM 工具安裝
Alibaba Cloud Linux 2 YUM 倉庫已經正式支持阿里巴巴 Dragonwell JDK,該 YUM 倉庫與 Aliyun Linux 17.1, Red Hat Enterprise Linux 7 以及 Centos 7 完全兼容。
對於使用 Alibaba Cloud Linux 2 操作系統的用戶,只需要執行 `sudo yum install -y java-1.8.0-alibaba-dragonwell` 就可以順利安裝。
如果用戶沒有使用 Alibaba Cloud Linux 2,但使用的 Linux 發行版和 Alibaba Cloud Linux 2 YUM 倉庫兼容,那么在 yum install
安裝前需要手動將 Alibaba Cloud Linux 2 YUM 倉庫添加到操作系統的 YUM 源里去。添加的方法很簡單,只需要在 /etc/yum.repos.d/ 里添加一個包含如下內容的 alilinux-plus.repo 文件即可。
# plus packages provided by Aliyun Linux dev team [plus] name=AliYun-2.1903 - Plus - mirrors.aliyun.com baseurl=http://mirrors.aliyun.com/alinux/2.1903/plus/$basearch/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/alinux/RPM-GPG-KEY-ALIYUN
為 Java 應用啟用 Alibaba Dragonwell
對於使用預編譯 Dragonwell 二進制包的 JDK 用戶,只需將應用腳本或者環境變量中的 JDK 目錄變量(一般是 JAVA_HOME) 指向上一步中安裝的 Alibaba Dragonwell 目錄。然后,重啟應用以使用 Alibaba Dragonwell JDK 配置。
如果用戶是通過 YUM 工具安裝的 Dragonwell JDK,YUM 會在安裝過程提示 JDK 的使用方法,提示的內容如下
======================================================================= Alibaba Dragonwell is installed to: /opt/alibaba/java-1.8.0-alibaba-dragonwell-8.0.0.212.b04-1.al7 You can set Alibaba Dragonwell as default JDK by exporting the following ENV VARs: $ export JAVA_HOME=/opt/alibaba/java-1.8.0-alibaba-dragonwell-8.0.0.212.b04-1.al7 $ export PATH=${JAVA_HOME}/bin:$PATH =======================================================================
總結
龍井 8.0.0-GA 的發布宣告着 Dragonwell 進入一個新征程,越來越多的新特性將會被開源。也希望社區小伙伴們多多支持,龍井 JDK 將和整個中國的 Java 開發者一起,為增強國內 Java 生態力量而努力,讓中國開發者的聲音被全世界所傾聽。