1. 程式人生 > >雲原生時代高效能Java框架—Quarkus(一)

雲原生時代高效能Java框架—Quarkus(一)

*[**——— Quarkus&GraalVM介紹、建立並啟動第一個專案**](http://blog.dongxishaonian.tech/?p=824)* ------ ***Quarkus系列博文*** - *[Quarkus&GraalVM介紹、建立並啟動第一個專案](http://blog.dongxishaonian.tech/archives/789(在新視窗中開啟))* - *構建Quarkus本地映象、容器化部署Quarkus專案* - *...* ------ ## Quarkus介紹 Quarkus 是一個為 **Java 虛擬機器(JVM)**和**原生編譯(native compilation)**而設計的全棧Kubernetes 原生 [Java 框架](https://www.redhat.com/zh/topics/cloud-native-apps/what-is-a-Java-framework),用於優化Java特別是Java專案的容器化,並使其成為[serverless](https://www.redhat.com/en/topics/cloud-native-apps/what-is-serverless)、[雲](https://www.redhat.com/en/topics/cloud)和 [Kubernetes](https://www.redhat.com/en/topics/containers/what-is-kubernetes) 環境的高效平臺。 Quarkus 可與常用 Java 標準、框架和庫協同工作,例如 Eclipse MicroProfile、Apache Kafka、RESTEasy(JAX-RS)、Hibernate ORM(JPA)、Spring、Infinispan、Camel 等。 Quarkus 的依賴注入解決方案基於 CDI(上下文和依賴注入),且包含一個擴充套件框架來擴充套件功能並將其配置、引導並整合到您的應用中。新增[擴充套件](https://quarkus.io/extensions/)就像新增依賴項一樣容易;或者,您可以使用 Quarkus 工具。 此外也是引人注目的一個特點,它還向 GraalVM(一種通用虛擬機器,用於執行以多種語言(包括 Java 和 JavaScript)編寫的應用)提供正確資訊,以便對應用進行原生編譯。 Rad Hat列出了一下清單來表明使用Quarkus的好處:[檢查清單](https://www.redhat.com/cms/managed-files/cl-4-reasons-try-quarkus-checklist-f19180cs-201909-a4-zh.pdf) ### Quarkus與傳統Java框架對比 ![img](http://images.dongxishaonian.tech/quarkus_metrics_graphic_bootmem_wide.png)Quarkus與傳統技術棧對比 來自官方的一張圖,展示了使用Quarkus框架開發專案和使用傳統框架開發的一些執行時資料明細對比,可以看到Quarkus專案在JVM中執行時所消耗的記憶體和介面響應能力要明顯好於傳統的Java技術棧。而將Quarkus編譯成本地可執行檔案(本地映象)之後,其優勢可以說非常明顯了。 ## GraalVM簡介 GraalVM是一種高效能的虛擬機器,它可以顯著的提高程式的效能和執行效率,非常適合微服務。其設計初衷是實現可以執行不同語言(Java、JavaScript、基於LLVM的語言(例如C和C ++)以及其他動態語言)編寫的應用程式。它消除了不同程式語言之間的隔閡,並實現了多語言共享執行時的互操作性。它可以獨立執行,也可以在OpenJDK,Node.js或Oracle資料庫的上下文中執行。 ![GraalVM system diagram](https://tva1.sinaimg.cn/large/007S8ZIlgy1ggtxy2x3gej30qo0f0whi.jpg) 對於Java應用程式,GraalVM可以帶來很多有價值的好處:更快地執行它們,通過指令碼語言(JavaScript, R, Python...)提供可擴充套件性或建立提前編譯的本機映像(native-image)。 更多關於GraalVM的資訊可參考:[此篇文章](http://blog.dongxishaonian.tech/archives/799)。 ## GraalVM安裝 本文我們使用[SDKMAN](https://sdkman.io/)來安裝GraalVM。SDKMAN是一款用於在大多數基於Unix的系統上管理多個軟體開發套件的並行版本的工具。它提供了一個方便的命令列介面(CLI)和API,用於安裝,切換,刪除和列出候選人。它以前被稱為Groovy enVironment Manager (GVM),受到了非常有用的RVM和rbenv工具的啟發,該工具在Ruby社群中廣泛使用。 ### 安裝SDKMAN 執行如下命令進行安裝: ```bash $ curl -s "https://get.sdkman.io" | bash $ source "$HOME/.sdkman/bin/sdkman-init.sh" ``` 執行如下命令,驗證是否已安裝ADKMAN: ```bash $ sdk version ``` ### 安裝GraalVM 執行如下命令: ```bash $ sdk list java ``` 可以看到SDKMAN列出了所支援的所有Java發行版 ![image-20200717142755813](https://tva1.sinaimg.cn/large/007S8ZIlgy1ggtycsyfe9j30wc0bugnb.jpg) 我們找到GraalVM的發行版 ![image-20200717142840033](https://tva1.sinaimg.cn/large/007S8ZIlgy1ggtydk3m8bj30xm05sdgb.jpg) 截至編寫本文時,GraalVM的最新版本為20.1.0.r11-grl,所以我們會安裝此版本。執行如下命令安裝GraalVM: ```bash $ sdk install java 20.1.0.r11-grl ``` 至此,GraalVM安裝完畢!我們可以執行如下命令來判斷GraalVM是否已安裝: ```bash $ java -version ``` ![image-20200717143216643](https://tva1.sinaimg.cn/large/007S8ZIlly1ggud02g9t0j315i02ywf2.jpg) ## 建立專案 我們有多種方式建立Quarkus專案 ### 使用Intellij IDEA建立Quarkus專案 點選選單欄File>New>Project... 建立新專案 ![image-20200717150609041](https://tva1.sinaimg.cn/large/007S8ZIlly1ggtzgp2cydj319c0qkwhx.jpg) 點選Next,並填寫適當的資訊,Next>Next...,建立完畢。 ### 使用Maven命令列建立Quarkus專案 執行如下命令,建立Quarkus專案: ```bash mvn io.quarkus:quarkus-maven-plugin:1.6.0.Final:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=getting-started \ -DclassName="org.acme.getting.started.GreetingResource" \ -Dpath="/hello" cd getting-started ``` 至此,建立專案完畢! ## 啟動專案 我們使用IDEA開啟專案 ![image-20200717152929281](https://tva1.sinaimg.cn/large/007S8ZIlly1ggu04ucrrnj31ee0u0td7.jpg) Quarkus並沒有類似Spring Boot、Helidon之類框架一樣的啟動類,我們需要通過執行Maven命令來啟動專案。 在IDEA控制檯執行如下命令來啟動專案: ```bash ./mvnw compile quarkus:dev ``` 啟動成功! ![image-20200717153314096](https://tva1.sinaimg.cn/large/007S8ZIlly1ggu08uubvzj32560qk0zj.jpg) 當然每次執行命令列會顯得不便,我們可以通過如下配置來配置專案快捷啟動: ![image-20200717153444892](https://tva1.sinaimg.cn/large/007S8ZIlly1ggu0aary6ej30xa08ymzi.jpg) 點選左上角"+"圖示新增一個Maven配置如左邊欄,在右邊欄中的Command line中填入"compile quarkus:dev",點選OK。 ![image-20200717153542033](https://tva1.sinaimg.cn/large/007S8ZIlly1ggu0bahsmuj315w0sqdir.jpg) 此時可以點下下圖所示圖示來便捷啟動專案 ![image-20200717153914940](https://tva1.sinaimg.cn/large/007S8ZIlly1ggu0eytva6j30na01ogln.jpg) ## 執行測試 開啟專案中的測試類,看到如下程式碼: ```java @QuarkusTest //1 public class ExampleResourceTest { @Test public void testHelloEndpoint() { given() .when().get("/hello") .then() .statusCode(200) //2 .body(is("hello")); } } ``` 1. 通過使用@QuarkusTest註解執行程式,可以指示JUnit在測試之前啟動應用程式。 2. 檢查HTTP響應狀態程式碼和內容。 預設情況下,測試將在埠8081上執行,以免與正在執行的應用程式衝突。Quarkus自動將RestAssured配置為使用此埠。如果要測試其他路徑,則可以使用@TestHTTPResource註解將被測試的URL直接注入到測試類的欄位中。該欄位的型別可以是字串,URL或URI。我們需要為該註解指定測試路徑的值。例如,如果我要測試對映到/myservlet的Servlet,只需在測試中新增以下內容: ```java @QuarkusTest public class ExampleResourceTest { @TestHTTPResource("/myservlet") URL testUrl; @Test public void testHelloEndpoint() { given() .when().get(testUrl) .then() .statusCode(200) .body(is("hello")); } } ``` 可以通過在專案配置檔案中配置quarkus.http.test-port屬性控制測試埠。 Quarkus還建立了一個名為test.url的系統屬性,該屬性值將被設定成基礎測試URL(BasePath)。 ## 總結 我們進入了雲原生、微服務的時代,我們告別了大型單體應用的龐大和複雜,並且收穫了微服務帶來的極大的好處 。但是一些問題也開始接踵而至。隨著微小服務的增多,曾經在單個應用上發生的多餘無用依賴、Java專案與生俱來的啟動過程緩慢、JIT優化問題擴散到了每個微服務上面。而且傳統的Java EE規範並沒有微服務的模式解決方案,問題很迫切需要解決。幸運的事,隨著Quarkus、Helidon等等一些新型Java開發框架的出現緩解了這個局面(以及目前Spring生態也開始了對GraalVM的大力支援),他們使Java變得更加本地化,不管是專案的體量方面還是資源消耗和執行效率方面都有顯著