前提介紹
本系列文章主要講解如何基于Quarkus技術搭建和開發"專為Kubernetes而優化的Java微服務框架"的入門和實踐,你將會學習到如何搭建Quarkus微服務腳環境及腳手架,開發Quarkus的端點服務,系統和應用層級的配置介紹與Quarkus的編程模型分析,創建Quarkus的應用Uber-jar文件以及集成到Kubernetes的環境中。
- 學習Quarkus的云原生微服務的零基礎搭建和開發實踐
- 分析Quarkus的編程模型以及與Kubernetes環境進行集成
面向的人群
Java軟件開發人員、系統架構師、微服務開發愛好者、運維部署人員等。
目前的狀況
近幾年由于云原生技術的普及,越來越多的用戶開始使用容器來運行微服務應用,隨著微服務的快速發展,spring全家桶已然成為了java框架的事實標準,包括單體應用使用的spring Framework和springboot,微服務間服務治理框架spring cloud,生態系統完善,各種組件層出不窮。
Java云原生化痛點
- 輕量化容器技術的誕生促使JVM服務變得更加臃腫
- 微服務架構的引入,使我們的服務顆粒度變得越來越小,輕量且能快速啟動的應用能夠更好的適應容器化環境。 以我們目前常規的Spring Boot應用來說,一般Restful服務的jar包大概是30M左右,如果我們將JDK以及相關應用打包成docker鏡像文件大概是140M左右。
- 常規的Go語言的可執行程序生成鏡像包一般不會超過50M。如何讓臃腫的Java應用瘦身使他易于容器化,成為Java應用云原生化需要解決的問題。
- 輕量化容器技術的誕生促使JVM服務內容使用量變得過大
- JVM對于內存的使用量變的越來越大,會促使FullGC的過多甚至OOM。
- SpringBoot的微服務應用啟動的速度越來越慢(JVM啟動速度)
- 從JVM啟動到真的應用程序執行需要經歷VM加載,字節碼文件加載,以及JVM為了提升效率,借助JIT(just in time)及時編譯技術對解釋執行的字節碼進行局部優化,通過編譯器生成本地執行代碼的過程,同時還需要加上了JVM內部垃圾回收所耗費的時間。
- 從JVM啟動到真的應用程序執行需要經歷VM加載,字節碼文件加載,以及JVM為了提升效率,借助JIT(just in time)及時編譯技術對解釋執行的字節碼進行局部優化,通過編譯器生成本地執行代碼的過程,同時還需要加上了JVM內部垃圾回收所耗費的時間。
典型的Java應用加載時間一般都是秒級起步,如果遇到比較大的應用初始花費幾分鐘都是正常的。 以往由于我們很少重新啟動Java應用,Java應用啟動時間長的問題一般很少暴露出來。
- 但是在云原生應用場景下,隨著粒度變的非常細,所以導致部署頻率過于頻繁
- 我們會經常不斷重啟應用來實現滾動升級或者無服務應用場景。 Java應用啟動時間長的問題就變成了Java應用云原生化亟待解決的問題。
Quarkus的介紹
- Quarkus定位為GraalVM和OpenJDK HotSpot量身定制的Kubernetes Native Java框架。
- Quarkus是紅帽開源的項目,借助開源社區的力量,通過對業界廣泛使用的框架進行了適配,并結合云原生應用的特點,提供了一套端到端的Java云原生應用解決方案。
- 雖然開源時間較短,但是生態方面也已經達到可用的狀態,自身包含擴展框架,已經支持像Netty、Undertow、Hibernate、JWT等框架,足以用于開發企業級應用,用戶也可以基于擴展框架自行擴展。
向原生邁進
對需要長時間運行的應用來說,由于經過充分預熱,熱點代碼會被HotSpot的探測機制準確定位捕獲,并將其編譯為物理硬件可直接執行的機器碼,在這類應用中Java的運行效率很大程度上是取決于即時編譯器所輸出的代碼質量。
HotSpot虛擬機中包含有兩個即時編譯器,分別是編譯時間較短但輸出代碼優化程度較低的客戶端編譯器(簡稱為C1)以及編譯耗時長但輸出代碼優化質量也更高的服務端編譯器(簡稱為C2),通常它們會在分層編譯機制下與解釋器互相配合來共同構成HotSpot虛擬機的執行子系統的。
新一代即時編譯器(Graal VM)
自JDK 10起,HotSpot中又加入了一個全新的即時編譯器:Graal編譯器,看名字就可以聯想到它是來自于前一節提到的Graal VM,Graal編譯器是作為C2編譯器替代者的角色登場的。
C2編譯器的問題
C2的歷史已經非常長了,可以追溯到Cliff Click大神讀博士期間的作品,這個由C++寫成的編譯器盡管目前依然效果拔群,但已經復雜到連Cliff Click本人都不愿意繼續維護的程度。
Graal編譯器本身就是由Java語言寫成,實現時又刻意與C2采用了同一種名為"Sea-of-Nodes"的高級中間表示(High IR)形式,使其能夠更容易借鑒C2的優點。
Graal編譯器比C2編譯器晚了足足二十年面世,有著極其充沛的后發優勢,在保持能輸出相近質量的編譯代碼的同時,開發效率和擴展性上都要顯著優于C2編譯器,這決定了C2編譯器中優秀的代碼優化技術可以輕易地移植到Graal編譯器上,但是反過來Graal編譯器中行之有效的優化在C2編譯器里實現起來則異常艱難。
Graal編譯器
Graal的編譯效果短短幾年間迅速追平了C2,甚至某些測試項中開始逐漸反超C2編譯器。
Graal能夠做比C2更加復雜的優化,如"部分逃逸分析"(Partial Escape Analysis),也擁有比C2更容易使用"激進預測性優化"(Aggressive Speculative Optimization)的策略,支持自定義的預測性假設等等。
Graal編譯器尚且年幼,還未經過足夠多的實踐驗證,所以仍然帶著"實驗狀態"的標簽,需要用開關參數去激活,這讓筆者不禁聯想起JDK 1.3時代,HotSpot虛擬機剛剛橫空出世時的場景,同樣也是需要用開關激活,也是作為Classic虛擬機的替代品的一段歷史。
Graal編譯器未來的前途可期,作為Java虛擬機執行代碼的最新引擎,它的持續改進,會同時為HotSpot與Graal VM注入更快更強的驅動力。
GraalVM的總結分析
GraalVM:JVM為了提升效率,借助JIT及時編譯技術對解釋執行的字節碼進行局部優化,通過編譯器生成本地執行代碼提升應用執行效率。
GraalVM是Oracle實驗室開發的新一代的面向多種語言的JVM即時編譯器,在性能以及多語言互操作性上有比較好的表現。與Java HotSpot VM相比,Graal借助內聯,逃逸分析以及推出優化技術可以提升2至5倍的性能提升。
GraalVM提供的靜態編譯功能,只能針對其編譯時能夠看得的封閉世界進行優化,對于那些使用了反射、動態加載、以及動態代理的代碼是無能為力的。
- 為了能讓我們日常的Java應用能夠正常運行起來,需要我們對應用所使用到的框架和類庫進行相關修改適配。
- 由于Java代碼所使用的類庫很多,這部分的工作量還是相當巨大的,雖然GraalVM已經推出超過一年多的時間,但是還是很少見到大規模Java應用轉移到這個平臺之上。
分享資源
獲取以上資源請訪問開源項目 點擊跳轉