真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

重塑云上的Java語言

音樂無國界,但是音樂人有國界。
云原生亦如此。雖沒有限定的編程語言,但應(yīng)用所使用的編程語言已經(jīng)決定了應(yīng)用部署運(yùn)行的行為。
Java 誕生于20年前,擁有大量優(yōu)秀的企業(yè)級框架,踐行 OOP 理念,更多體現(xiàn)的是嚴(yán)謹(jǐn)以及在長時間運(yùn)行條件下的穩(wěn)定性和高性能。反觀如今,在要求快速迭代交付的云場景下,語言的簡單性似乎成了首要的要求,而傳統(tǒng)的 Java 語言顯得有一些過于重量了。
本文由阿里巴巴 JVM 團(tuán)隊(duì)技術(shù)專家郁磊(花名:梁希)分享 JVM 團(tuán)隊(duì)是如何面對和處理集團(tuán)巨大的業(yè)務(wù)規(guī)模和復(fù)雜的業(yè)務(wù)場景的。

ElasticHeap

Java 常因?yàn)楹馁Y源而受詬病,其中最顯著一點(diǎn)就是 Heap 對內(nèi)存的占用,即便沒有請求在處理也沒有對象分配,進(jìn)程仍然會保留完整的堆內(nèi)存空間,保障 GC 進(jìn)行分配內(nèi)存和操作內(nèi)存的快速敏捷。
AJDK ZenGC/ElasticHeap 雙十一全面支持核心鏈路上百應(yīng)用和數(shù)十萬實(shí)例。

JDK12 開始支持固定時間的觸發(fā) concurrent mark 并在 remark 中收縮 Java 堆歸還內(nèi)存的功能,然而并未解決在 stw 中增加暫停時間的問題,因此無法在每次 young GC 時做內(nèi)存歸還。 ElasticHeap 在并發(fā)異步線程中完成內(nèi)存處理反復(fù) map/unmap 以及 page fault 的開銷,因此任意一次 young GC 都可以敏捷的及時歸還內(nèi)存,或重新恢復(fù)內(nèi)存使用。

ElasticHeap 阿里巴巴實(shí)戰(zhàn)

ElasticHeap場景1:可預(yù)測的流量高峰



ElasticHeap 場景 2 :單機(jī)運(yùn)行多個 Java 實(shí)例

多個 Java 實(shí)例接受的流量任務(wù)較為隨機(jī),峰值不會重疊,在閑時可以有效降低多個實(shí)例整體的內(nèi)存占用,提高部署密度。
雙11驗(yàn)證核心交易系統(tǒng)使用 ElasticHeap 進(jìn)行低功耗模式運(yùn)行,大幅降低 WSS(Working Set Size) 規(guī)模的實(shí)例。


靜態(tài)編譯

很多云上的新應(yīng)用不約而同地選擇了 Go 語言,很大的原因是 Go 應(yīng)用對運(yùn)行時沒有依賴,靜態(tài)編譯的程序啟動速度快,也不需要通過 JIT 來預(yù)熱。在阿里有大量 Java 代碼的前提下,我們是如何為 Java 注入這方面的能力的呢?
Java 靜態(tài)編譯技術(shù)是一種激進(jìn)的 AOT 技術(shù),通過單獨(dú)的編譯階段將 Java 程序編譯為本地代碼,在運(yùn)行時無需傳統(tǒng) Java 虛擬機(jī)和運(yùn)行時環(huán)境,只需操作系統(tǒng)類庫支持即可。其工作基本原理如下圖所示。靜態(tài)編譯技術(shù)實(shí)現(xiàn)了 Java 語言與原生 native 程序的“合體”,將原本的 Java 程序編譯成為了一個自舉的具有 Java 行為的原生 native 程序,由此兼有 Java 程序和原生 native 程序的優(yōu)點(diǎn)。
JVM 團(tuán)隊(duì)與 SOFAStack 團(tuán)隊(duì)密切合作,在中間件應(yīng)用上率先實(shí)現(xiàn)靜態(tài)編譯的落地。將一個應(yīng)用的啟動速度從 60 秒優(yōu)化到 3.8 秒,雙十一期間靜態(tài)編譯的應(yīng)用運(yùn)行穩(wěn)定,沒有故障, GC 停頓時間在 100 毫秒,在業(yè)務(wù)允許范圍之內(nèi),內(nèi)存占用和 RT 與傳統(tǒng) Java 應(yīng)用持平。


綜上所述,靜態(tài)編譯的應(yīng)用在穩(wěn)定性、資源占用、RT 響應(yīng)等各方面指標(biāo)與傳統(tǒng) Java 應(yīng)用基本持平的狀況下,將啟動時間降低了 2000% 。

Wisp2

當(dāng)你用時下最酷炫的 Vert.X 開發(fā)一個簡單的 Web 服務(wù),準(zhǔn)備體驗(yàn)一下最強(qiáng)的性能, QA 同學(xué)拿來一臺 1C 2G 的容器讓你壓一下,你卻發(fā)現(xiàn)你怎么也拼不過別人 Go 應(yīng)用。研究之后發(fā)現(xiàn),原來協(xié)程模型在這樣的少核心的情況下性能要好很多。是時代變了, Java 落伍了?
AJDK Wisp2 回答了這個問題: Java 同樣可以擁有高性能的協(xié)程。今年是 Wisp2 大規(guī)模上線的第一年, Wisp2 具有如下特點(diǎn): 在整個Java runtime中支持了協(xié)程調(diào)度,線程(比如 Socket.getInputStream().read() )阻塞會變成更輕量的協(xié)程切換。 完全兼容 Thread API ,在開啟 Wisp2 的 JDK 中,Thread.start() 實(shí)際創(chuàng)建的是一個協(xié)程(輕量級線程),可以類比 Go 只提供協(xié)程關(guān)鍵字 go 而沒有暴露線程接口;我們同樣只提供創(chuàng)建協(xié)程的方式,應(yīng)用可以透明切換到協(xié)程。 支持 work stealing ,調(diào)度策略特別適合 web 場景,在高壓力下調(diào)度開銷極小。
在今年雙十一, Wisp 支持了上百應(yīng)用,十萬級容器,其中 90% 的容器已經(jīng)升級到 Wisp2 。


我們可以看到峰值附近, Wisp2 機(jī)器的 CPU 要低 7%( Wisp1 更低,Wisp2的取向是 RT ,因此 CPU 會高一些)左右,這主要是輕量級調(diào)度所節(jié)省的 sys CPU 。 0 點(diǎn)的 CPU 是相等的,這也說明一點(diǎn): Wisp2 解決的是調(diào)度開銷,當(dāng) CPU 低,調(diào)度沒有壓力時是看不出差距的。


從 RT 角度看, Wisp2 機(jī)器的 RT 要低 20% 左右, RT 減少明顯的一個原因是這批機(jī)器的 CPU 壓力很大,協(xié)程的調(diào)度優(yōu)勢更容易體現(xiàn)出來。這樣的優(yōu)勢可以幫助系統(tǒng)摸高到更高的水位,整體地提高利用率而擔(dān)心 RT 過高導(dǎo)致系統(tǒng)雪崩。

FDO

雙十一正零點(diǎn)相對后面幾分鐘會有一個明顯的 CPU 峰值,根據(jù)數(shù)據(jù)分析,主要原因是雙十一零點(diǎn)觸發(fā)了 JIT 編譯。 舉個例子,程序里有邏輯: if (is1111(LocalDate.now())) { branch2 } else { branch3 } 假設(shè)預(yù)熱時一直在走 branch3 ,那么 JIT 有理由相信后續(xù)基本也都會走 branch3 ,而不會對 branch2編譯。在零點(diǎn)時,我們進(jìn)入 branch2 ,此時就需要觸發(fā)退優(yōu)化重新編譯方法。我們來看 AJDK 如何通過 profiling 解決這個問題。

退優(yōu)化原理及其危害

JDK 運(yùn)行代碼的時候,采用分層編譯的方式對 Java 方法進(jìn)行動態(tài)編譯。在最高等級(峰值性能最好)的編譯中,出于性能的考慮,編譯的時候會根據(jù)收集的信息做一些比較樂觀的假設(shè),一旦這些假設(shè)條件不滿足了,就會出現(xiàn)退優(yōu)化的現(xiàn)象。比如某個熱點(diǎn)方法中某段代碼僅會在雙十一中執(zhí)行,那么在預(yù)熱過程中這段代碼不會被編譯,雙十一到來時這段代碼一旦被執(zhí)行,就會觸發(fā)整個方法的退優(yōu)化。
發(fā)生退優(yōu)化有兩個方面的負(fù)面影響,一是需要運(yùn)行的方法由高效率的編譯執(zhí)行變成了解釋執(zhí)行,運(yùn)行速度降低百倍以上;二是流量高峰期退優(yōu)化的方法會很快被重新編譯,編譯線程會消耗 CPU 。因此在雙十一這種流量短時間劇增且與預(yù)熱流量不太一樣的場景下,退優(yōu)化的危害會特別明顯。

通過 FDO 減少退優(yōu)化

FDO 是 feedback directed optimization 的縮寫,即參考以往 JVM 運(yùn)行時的編譯信息,指導(dǎo)本次運(yùn)行時進(jìn)行更好的編譯。具體的,我們采用了兩個層面的方法來減少退優(yōu)化。 將每次運(yùn)行時的退優(yōu)化信息記錄到文件中,下次運(yùn)行時讀取這個文件,在決定是否做樂觀假設(shè)的時候參考文件中的信息做判斷,從而減少退優(yōu)化的概率。
信息顯示出現(xiàn)最多的退優(yōu)化與 if-else 相關(guān),占總數(shù)量的一半以上。我們提供了一個方法根據(jù)以往出現(xiàn) if-else 退優(yōu)化的信息,關(guān)閉某個路徑上所有相關(guān)的樂觀假設(shè)。

雙十一中 FDO 的效果

FDO 今年雙十一上線,目標(biāo)解決兩個問題: 1、雙十一 0 點(diǎn)流量高峰和退優(yōu)化/編譯高峰疊加造成的 CPU 使用率脈沖過高。
2、預(yù)熱效率低,壓測經(jīng)過前長時間預(yù)熱后,增大流量時仍然伴隨著大量的編譯及退優(yōu)化。
針對第一個問題,我們收集了雙十一高峰第一分鐘的退優(yōu)化/C2 編譯次數(shù)以及 CPU 數(shù)據(jù)。
可見開啟 FDO 后高峰期 C2 編譯數(shù)目減少約 45% ,退優(yōu)化數(shù)目減少約 70% 。
CPU 數(shù)據(jù)上,高峰期第一分鐘內(nèi)開啟 FDO 后 CPU 由約 67.5 降低到 63.1 ,降低約 7.0% 。


第二個目標(biāo)可以通過壓測第一分鐘的 CPU 數(shù)據(jù)驗(yàn)證。
開啟 FDO ,壓測第一分鐘 CPU 使用率由 66.19 降低到 60.33% ,降低約 10% 。

Grace

ZProfiler 一直是全集團(tuán)排查 Java 應(yīng)用各類問題的利器,而 Grace 作為其平臺化的版本,對其實(shí)施了一系列的優(yōu)化,從原來的單機(jī)版本到現(xiàn)在的 Master/Worker 架構(gòu),同時引入了任務(wù)排隊(duì)機(jī)制,在高壓力情況下對用戶的任務(wù)進(jìn)行排隊(duì)從而解決 Worker 不堪重負(fù)的問題。在可維護(hù)性、拓展性、以及用戶體驗(yàn)上得到了質(zhì)的提升,為后續(xù)工具平臺的上云、開源事項(xiàng)打下了夯實(shí)的基礎(chǔ)。
目前已經(jīng)集成了 Heap Dump 功能,在繼承 ZProfiler 功能的基礎(chǔ)上做了一定的優(yōu)化,提升了解析引擎的版本,支持更全面的 OQL 語法等等。


JDK11

JDK8 作為一個經(jīng)典版本,正被大規(guī)模使用,雖然從 JDK6 和 7 遷移上來有一定的陣痛,但是升級后普遍的反饋是:“真香”。
OpenJDK 8的下一個穩(wěn)定版本是 OpenJDK 11 。JVM 團(tuán)隊(duì)自然會在這個方向上積極跟進(jìn),目前 AJDK11 支持了 AJDK8 的 Wisp2 、多租戶特性。本次雙十一的部分集群已經(jīng)上線到 JDK11 ,表現(xiàn)穩(wěn)定。
升級 JDK11 是否會和升級 JDK8 一樣給我們帶來同樣的的驚喜呢?在 JDK11 上我們可以體驗(yàn)到最新的 ZGC 。

ZGC

JDK11 引入了一個重要特性: ZGC 內(nèi)存垃圾回收器。這個垃圾回收器號稱能夠在幾十 GB 至若干 TB 的堆上把暫停時間保持在 10ms 以內(nèi)。許多 Java 開發(fā)者苦于過去的垃圾回收器的暫停時間帶來延遲, ZGC 短暫停的特性未來無疑會成為 Java 開發(fā)者的新寵。
目前 ZGC 在 OpenJDK 中仍然處于實(shí)驗(yàn)特性,而且 JDK11 尚未在產(chǎn)業(yè)界完全普及, JDK11 只支持 Linux 上的 ZGC( MacOS 和 Windows 的 ZGC 預(yù)計(jì)在 2020 年 3 月發(fā)布的 JDK14 版本才會支持),許多 Java 開發(fā)者仍然只能垂涎欲滴,處于觀望狀態(tài)。
向來敢于吃螃蟹的我們豈能望而卻步?阿里 JVM 團(tuán)隊(duì)和數(shù)據(jù)庫團(tuán)隊(duì)已經(jīng)開始讓數(shù)據(jù)庫應(yīng)用運(yùn)行在 ZGC 上,并根據(jù)運(yùn)行的效果對 ZGC 進(jìn)行了相應(yīng)的改進(jìn)工作,包括 ZGC 的頁緩存機(jī)制優(yōu)化、ZGC的觸發(fā)時機(jī)優(yōu)化等等。
從 9 月開始,兩個團(tuán)隊(duì)推動線上數(shù)據(jù)庫應(yīng)用在 ZGC 上運(yùn)行,目前已經(jīng)穩(wěn)定運(yùn)行兩個月,并順利通過雙十一大考。線上反饋的效果可喜可賀: 1、 JVM 暫停時間保持在官方的 10ms 以內(nèi); 2、 ZGC 大大改善了線上運(yùn)行集群的平均 RT 與毛刺指標(biāo)。

小結(jié)

從上述的功能特性可以看到 AJDK 已經(jīng)從一個傳統(tǒng)的 Managed Runtime 脫胎換骨。今后 AJDK 將繼續(xù)致力于提高云上的應(yīng)用的開發(fā)體驗(yàn),通過底層的創(chuàng)新為上層應(yīng)用提供更多的可能。

在 Dragonwell 上使用 AJDK 功能

上述的這些經(jīng)過雙十一考驗(yàn)的功能都將隨著 Dragonwell 陸續(xù)開源和交付到廣大用戶手中,敬請關(guān)注。
Alibaba Dragonwell 8 是一款免費(fèi)的 OpenJDK 發(fā)行版。它提供長期支持,包括性能增強(qiáng)和安全修復(fù)。Alibaba Dragonwell 8 目前支持 X86-64/Linux 平臺,在數(shù)據(jù)中心大規(guī)模 Java 應(yīng)用部署情況下, 可以大幅度提高穩(wěn)定性、效率以及性能。Alibaba Dragonwell 8 是 OpenJDK 的下游( friendly fork ),使用了和 OpenJDK 一樣的 license。Alibaba Dragonwell 8 與 Java SE 標(biāo)準(zhǔn)兼容,用戶可以使用 Alibaba Dragonwell 8 開發(fā)和運(yùn)行 Java 應(yīng)用程序。此次開源的 Alibaba Dragonwell 8 是阿里巴巴內(nèi)部 OpenJDK 定制版 AJDK 的開源版本, AJDK 為在線電商,金融,物流做了結(jié)合業(yè)務(wù)場景的優(yōu)化,運(yùn)行在超大規(guī)模的,1,000,000+ 服務(wù)器的阿里巴巴數(shù)據(jù)中心。
近期我們正在緊密籌備 Alibaba Dragonwell 11 的 release 。 Dragonwell 11 是基于 OpenJDK 11 的 Dragonwell 發(fā)行版本,擁有更多特性,可以更多地為云上場景賦能,模塊化更加清晰,并將獲得長期的支持,因此推薦大家關(guān)注和適時升級。


原文鏈接
本文為阿里云內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。

文章題目:重塑云上的Java語言
網(wǎng)站URL:http://weahome.cn/article/jscjhi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部