開發與維運

Java 正青春:現狀與技術趨勢報告

背景

1991 年,James Gosling 帶領團隊開始了一個叫"Oak"的項目,這個就是 Java 的前身。1995 年,Java1.0 發佈。“Write once, run anywhere"這句 Java 口號想必大家耳熟能詳。Java 剛開始出現的時候主要面向 Interactive Television 領域,直至後來幾年的發展,當時的 SUN(後來在 2010 年被 Oracle 收購)一度想用 Java 來打造桌面的網絡操作系統,取代當時如日中天的 Windows。不過 Java 後來的發展,不曾想雖未在桌面領域內取得多大的建樹,出乎意料地,卻在企業級應用領域開花結果,佔據瞭如今幾乎統治的地位。失之東隅,卻收之桑榆。

JavaSE 開源現狀

Sun 在 2006 年的 Java One 大會上,宣佈 Java 技術開源,隨後 2006 年底在 GPL 協議下發布 HotSpot 以及 javac,這是 Java 發展中的里程碑事件。阿里巴巴最早在 2012 簽署 OCA,並參與到了 OpenJDK 的開發。

image.png

OpenJDK 是 JavaSE 開源的 Reference Implementation。在 JavaOne 2017 的 Keynote 上 (2018 年 JavaOne 被 Oracle 重命名為 CodeOne),Oracle 承諾將開源所有的 OracleJDK 裡包含的商業實現功能[1]。

image.png

在 2018 年發佈的 Java11, Oracle 已經讓 OpenJDK 和 Oracle JDK 兩者的二進制文件在功能上儘可能相互接近,儘管 OpenJDK 與 OracleJDK 兩者在一些選項之間仍然存在一些差異[2]。

另外,除了 OpenJDK 這條主線,在最近的幾年裡,Java 基礎技術的開源有愈演愈烈趨勢:2017 年,IBM 將內部使用 20 多年之久的 J9 虛擬機開源,並貢獻到 Eclipse Foundation, 而隨後 2018 年,Oracle 開源 GraalVM 1.0,其核心包含用 Java 寫的Just-in-Time compiler/Graal, SubstrateVM 以及支持多語言解釋器的 Truffle 框架。各個企業開源的主要動機,想通過開源構建並受益於一個更為強大的語言生態系統。

雲 + 開源結合在一起,使得普通開發者以較低的門檻獲得一流工具(鏈)的使用和體驗,任何一家企業都可以像任何大型組織一樣,使用的相同技術(democratizing),這是開發者的黃金時代。

Java is Still Free: 你該選擇什麼樣的 JDK?

Java 仍然免費,但隨著 OracleJDK License 變化開始轉向收費,OpenJDK 會逐漸取代 OracleJDK 成為市場主流,這點也可以從 JVM 2020 生態報告中看出趨勢:OracleJDK 從前一年的 70% 的開發者選擇使用率降到 2020 年的 34%。

OracleJDK 收費,在客觀上也加劇了 OpenJDK 生態的碎片化趨勢,出現了包括 Alibaba Dragonwell 在內的多個基於 OpenJDK 的可選實現。

企業在選擇使用那個 Java Vendor 的 JDK 版本時,幾個方面的考慮因素可以參考:

  • 安全與穩定:是否會及時同步上游的最新更新,包括安全補丁,關鍵的問題修復等。
  • JavaSE 標準兼容 :是否與標準 Java 兼容。
  • 性能與效率:是否可以在問題診斷,性能調優方面提供有效的工具支持,幫助一線的開發同學高效地解決 Java 問題。在 JVM,到 JDK (Class library) 層面,是否有面向企業業務場景的優化特性,可以幫助提升資源的利用率,生產系統的穩定性等等。
  • 快速的新技術採納:伴隨收費,Oracle 管理 Java 版本生命週期採用了 Long Term Support(LTS) 的概念,Oracle 每三年會指定一個 LTS 的 Java 版本, Java 8/11 都是 LTS 版本。大部分企業,尤其是大中型企業很難跟上 Java 每六個月一發布的節奏,像 Java 12,13 這樣的 Feature Release(FR) 版本。那麼問題來了,如果你選擇 Stay 在 LTS 版本上,比如 Java 11,在新版本 (Java11+) 發佈的 JVM/JDK 技術,是否可以在不升級的情況下,提前享受這些技術紅利?

這裡分享下 Alibaba Dragonwell 在這些方面的計劃與思考。

Alibaba Dragonwell 是阿里巴巴內部廣泛使用的 AJDK (AlibabaJDK) 的開源版本,Alibaba Dragonwell 作為基石,支撐了阿里經濟體內幾乎所有的 Java 業務,經過了雙 11 等大促的考驗。Alibaba Dragonwell 主要針對的場景是數據中心大規模 Java 應用部署情況下,Java 應用穩定性、效率以及性能的優化與提高。

2019 年 3 月阿里開源 Alibaba Dragonwll 8.0.0,我們也一直正在踐行開源時候的承諾,AJDK 內部使用的特性在逐步開源。到剛剛發佈 Alibaba Dragonwell 8.3.3,我們已經開源了 JWarmup,ElasticHeap,多租戶,JFR 等眾多功能,協程 Wisp 2.0,GCIH 等也在開源的規劃上。

image.png

同時,Alibaba Dragonwell 作為 OpenJDK 的下游,每個發行版都會同步上游最新更新,包括安全更新,問題修復等,並經過阿里內部大規模的應用集群測試。

在新技術 Adoption 方面,Alibaba Dragonwell 目前發佈和維護了 Java 8,11 兩個 LTS 版本,阿里 JVM 團隊會根據實際業務狀況,移植 Java11+ 的相關功能到 Java 8 和 11 兩個版本,這樣 Alibaba Dragonwell 用戶可以在不跟進 Java 12,13 等這些 FR 版本的情況下,提前享受這些功能帶來的技術紅利。

OpenJDK技術趨勢

縱觀 Java 技術 20 多年的發展,始終圍繞著兩大主題:Productivity 以及 Performance。在很多情況下,Java 在設計上 Productivity 是優於 Performance 考慮的。Java 引入的 Garbage Collector 把程序員從複雜的內存管理中解脫出來,但在另一方面 Java 應用始終困擾於 GC 暫停時間的影響。Java 基於棧式虛擬機的中間字節碼設計,很好地抽象了不同平臺 (Intel, ARM 等) 的差異性,同時通過 Just-in-Time (JIT) 編譯技術,解決的 Java 應用 peak 性能, 但在另一方面 JIT 不可避免引入了 Warmup 的代價,正常情況下 Java 程序永遠需要先 load class,解釋執行,然後再到高度優化的代碼執行。

如果從 JVM 視角來總結梳理下目前 OpenJDK 社區正在發生,孵化的相關技術,主要從工具,GC,編譯器,以及 Runtime 四個方面進行一個主要概括:

image.png

JFR/JMC

Oracle 從 Java 11 開源了其之前一直作為商業功能的 JFR,JFR 是功能強大的 Java 應用問題診斷與性能剖析工具。阿里巴巴也是作為主要的貢獻者,與社區包括 RedHat 等,一起將 JFR 移植到了 OpenJDK 8, 預計 2020 年 7 月即將發佈的 OpenJDK 8u262 (Java8) 將會默認帶有 JFR 功能,這樣 Java 8 的用戶可以基於這個版本免費使用 JFR 功能。

ZGC/Shandoath

無論是 Oracle 在 Java 11 發佈的 ZGC,還是 RedHat 已經做了好幾年的 Shandoath,都實現了 concurrent copy GC,解決 Large Heap 情況下的 GC 停機性能。ZGC 最新狀態,在 9 月份即將發佈的 JDK 15,ZGC 將從 Experimental 功能變為生產可用 [3] 。實際上,在 AJDK 11 上,阿里巴巴團隊 JVM 團隊已經做了大量 Java 11+ 到 Java 11 的 ZGC 移植工作,以及相關問題修復,2019 年雙 11 和阿里數據庫團隊一起,讓數據庫應用運行在 ZGC 上,100+ GB Heap 情況下 GC 暫停時間可以保持在 <10ms 以內, 詳細討論參考[4]。

Graal

用 Java 開發的新一代 Just-in-Time 編譯技術,用來替代目前 HostSot JVM 的 C1/C2 編譯器,OpenJDK 上的 Ahead-of-Time (AOT) 技術也是基於 Graal 編譯器開發。

Loom

OpenJDK 社區協程項目,對應於 AJDK 的 Wisp 2.0 實現,詳細討論可以參考[5]。

進擊的 Java:面向未來演進

2020,站在一個全新的節點上,本文也從三個大的方面 Cloud Native, AI,以及多語言生態三個方面展望下未來的發展,有些討論本身是超越 Java 本身的。

面向 Cloud Native 的語言進化

雲原生時代,軟件的交付方式發生的根本性變化。以 Java 為例,在之前 Java 開發者交付的是應用本身,具體體現在以 "jar", "war" 的形式交付, 而云原生則是以 Container 為交付單位的:

image.png

在運行方面,面向 Cloud Native 的應用要求:

  • Reactive
  • Always Watching
  • Extreme low memory footprint
  • Quick boot time

Java 語言作為企業計算,互聯網領域的王者,擁有一致性,豐富的構建在 Java 語言之上的生態系統, 豐富的三方庫,多樣的 Serviceability 支持等,隨著雲時代應用微服務化,Serverless,這些新的架構逐漸觸及到了 Java 程序速度提升的天花板 —— Java 自身的啟動運行開銷。

在 Cloud Native 這個新的上下文裡, 我們談論語言的進化,絕不僅僅限於運行時,編譯器層面, 新的計算形態一定伴隨著編程模型的變革,這涉及圍繞程序語言的 Library,Framework,Tools 等一系列配套的改革。從目前業界來看,也有不少的項目正在發生:配合 GraalVM/SVM (Java 靜態編譯技術) 的下一代編程框架 Quarkus, Micronaut, 以及 Helidon,Quarkus 更是提出了“container first” ,他們提倡的分層的 lightweight uber-jar 的概念正是符合了 container 交付這一趨勢。而 Red Hat 的 Java 團隊與 OS 團隊合作的"Checkpoint Restore Fast Start-up"技術 (AZul 在 JVM 技術峰會 '2019 上也提出過類似的想法) 則是在更加底層的技術棧上解決 Java 快速拉起問題。

在 Java for Cloud Native 方向,我們也開展了相關研發工作。Java 是靜態語言,但是包含了大量的動態特性,包括反射,Class Loading,Bytecode Instrument (BCI) 等等,這些動態特性本質上都是違反 GraalVM/SVM 所要求的 Closed-World Assumption (CWA) 原則,這也是導致傳統跑在 JVM 的 Java 應用不容易在 SVM 編譯運行的主要原因。阿里巴巴 JVM 團隊對 AJDK 做了靜態化裁剪,務求在 Java 靜/動態特性之間找到一個確定的邊界,從 JDK 的層面為 Java 靜態編譯提供可能性。同時向上,與螞蟻中間團隊合作,定義面向靜態編譯的 Java 編程模型,通過編程框架來約束 - Java 應用的開發是面向靜態編譯友好的。我們靜態編譯了基於螞蟻開源中間件 SOFAStack 構建的服務註冊中心 Meta 節點應用,相較於傳統 的運行在 JVM上,性能有量級的提升:服務啟動時間降低了 17 倍,可執行文件大小降低了 3.4 倍,運行時內存降低了一半。詳見[6]。

AI 的興起,編程語言異構計算的新挑戰

2005 年,時任 Intel CTO 的 Justin Rattner,說過 “We are at the cusp of a transition to multicore, multithreaded architectures”, 在前後的十幾年中, 編程語言與編譯器領域一直在努力面向 parallel architectural paradigm 做優化探索。隨著 AI這些年的興起, 不同的時間節點,相似的場景,面向 FPGA/GPU 異構計算場景,對編程語言與編譯器領域提出了新的挑戰。

除了傳統 Compiler 諸如 IBM XL Compilers, Intel Compilers 等做的 Automatic Parallelizing 工作,在極致性能探索方面,基於多面體模型 (polytope model) 的編譯優化技術作為解決程序並行化、數據局部性優化的一種手段,成為編譯優化領域的研究熱點。

而在 Parallel Languages 層面,對 C&C++ 開發人員,CUDA 的出現降低了 GPU 的編程門檻,但 GPU 和 CPU 兩種硬件模型本質區別,導致過高的開發成本,需要學習和了解更多底層硬件細節,還更不用說更高級語言的開發語言像 Java 等所面臨的底層硬件模型與高級語言之間巨大的 GAP。

在 Java 領域,最早在 JVM 技術峰會 '2014,AMD 曾經分享過他們的 Sumatra 項目,嘗試實現 JVM 與 Heterogeneous System Architecture 目標硬件交互。而在最近,由 The University of Manchester 發起的 TornadoVM 項目,實現包含:一個 Just-in-Time 編譯,支持從 Java bytecode 到 OpenCL 的映射,一個優化的運行時引擎,以及可以保持 Java 堆和異構設備堆內存一致性的內存管理器。TornadoVM 的目標是開發人員不需要了解 GPU 編程語言或者相關的 GPU 體系結構知識就可以編寫面向異構的並行程序。TornadoVM 可以透明地運行在 AMD GPUs, NVIDIA GPUs, Intel integrated GPUs 以及 multi-core CPUs 上。

在通用 CPU 領域, OpenJDK 社區的 Vector API 項目 (Panama 的子項目),依賴 CPU 的 SIMD 指令,獲得計算性能的成倍提升,Vector API 在大數據,AI 計算也有非常廣的應用場景。阿里 JVM 團隊把 Vector API 移植到了 AJDK 11,後續會開源到 Alibaba Dragonwell,分享下我們獲得的基礎性能數據:

image.png

時間 (單位: milliseconds) 越短,性能越好

Polyglot Programing,鏈接多語言生態

Polyglot Programming 並不是一個新的概念。在 Managed Runtime 領域, 2017 年 IBM 開源 Open Managed Runtime(OMR), 以及 2018 年 Oracle 開源 Truffle/Graal 技術。OMR 和 Graal 技術讓開發人員實現一個新的語言成本大幅下降。前者 OMR 以 C、C++ 組件的形式提供了 Garbage Collection (GC), Just-in-Time (JIT) 以及 Reliability, availability and serviceability (RAS,工具)等, 開發人員可以依賴這些組件,通過 'glue' 的方式基於這些組件實現自己的高性能語言。而後者 Truffle/Graal, Truffle 是一個依賴 AST parser 實現新的語言的 Java 框架,本質上是將你的新的語言映射到 JVM 世界。不同於 Scala, JRuby 這些圍繞 JVM 生態本身構建的語言,他們本質是還是 Java, 無論是 OMR, 還是 Truffle/Graal,他們都提供了生產級的 GC,JIT,以及 RAS 服務支持,新開發的語言完全不需要再重新實現這些底層技術。

從業界來看,面向特定領域的 Domain Specific Language (DSL) 語言已經有向這些技術遷移的趨勢,高盛正在與 Graal 社區合作,把他們的 DSL 遷移到 Graal 上。另外 Ruby/OMR, Python/Graal, JS/Graal,WASM/Graal 等這些真正鏈接不同語言生態的項目,也正在迅速發展起來。

回到 AJDK, Graal 已經在 AJDK 8 開始支持, JS/Graal 這樣成熟的技術,已經在阿里內部業務上線。

最後

Java 是一項二十多年前被髮明出來的技術,她歷經磨難,幾易其主,但卻歷久彌新。這篇報告旨在為 Java 的開發者們梳理下目前的 Java 技術現狀,以及討論在雲,AI 等這些重要領域內 Java 技術的演進趨勢。在介紹的相關部分,我們也穿插了阿里的一些工程實踐。作為世界上最大的 Java 用戶之一,我們也一直在探索把前沿的 Java 技術,通過在阿里豐富的業務場景的試驗,真正把這些技術應用於真實的生產環境。我們也非常樂於分享和貢獻 Java 領域的經驗、實踐與技術洞見,共同促進 Java 的發展。

參考

[1]https://www.infoq.com/news/2017/10/javaone-opening/
[2]https://www.oracle.com/technetwork/java/javase/11-relnote-issues-5012449.html#Diffs
[3]https://openjdk.java.net/jeps/377
[4]https://mp.weixin.qq.com/s/FQpvT5wIy9xwhX2jHMU7aw
[5]https://mp.weixin.qq.com/s/K1us6aH-gjHsWGhQ3SulFg
[6]https://www.infoq.cn/article/uzHpEbpMwiYd85jYslka

Leave a Reply

Your email address will not be published. Required fields are marked *