云原生時代高性能Java框架—Quarkus(一)

——— Quarkus&GraalVM介紹、創建并啟動第一個項目


Quarkus系列博文


Quarkus介紹

Quarkus 是一個為 Java 虛擬機(JVM)和原生編譯而設計的全堆棧 Kubernetes 原生 Java 框架,用于專門針對容器優化 Java,并使其成為無服務器、云和 Kubernetes 環境的高效平臺。

Quarkus 可與常用 Java 標準、框架和庫協同工作,例如 Eclipse MicroProfile、Apache Kafka、RESTEasy(JAX-RS)、Hibernate ORM(JPA)、Spring、Infinispan、Camel 等。

Quarkus 的依賴注入解決方案基于 CDI(上下文和依賴注入),且包含一個擴展框架來擴展功能并將其配置、引導并集成到您的應用中。添加擴展就像添加依賴項一樣容易;或者,您可以使用 Quarkus 工具。

此外也是引人注目的一個特點,它還向 GraalVM(一種通用虛擬機,用于運行以多種語言(包括 Java 和 JavaScript)編寫的應用)提供正確信息,以便對應用進行原生編譯。

Rad Hat列出了一下清單來表明使用Quarkus的好處:檢查清單

Quarkus與傳統Java框架對比

imgQuarkus與傳統技術棧對比

來自官方的一張圖,展示了使用Quarkus框架開發項目和使用傳統框架開發的一些運行時數據明細對比,可以看到Quarkus項目在JVM中運行時所消耗的內存和接口響應能力要明顯好于傳統的Java技術棧。而將Quarkus編譯成本地可執行文件(本地鏡像)之后,其優勢可以說非常明顯了。

GraalVM簡介

GraalVM是一種高性能的虛擬機,它可以顯著的提高程序的性能和運行效率,非常適合微服務。其設計初衷是實現可以運行不同語言(Java、JavaScript、基于LLVM的語言(例如C和C ++)以及其他動態語言)編寫的應用程序。它消除了不同編程語言之間的隔閡,并實現了多語言共享運行時的互操作性。它可以獨立運行,也可以在OpenJDK,Node.js或Oracle數據庫的上下文中運行。

GraalVM system diagram

對于Java應用程序,GraalVM可以帶來很多有價值的好處:更快地運行它們,通過腳本語言(JavaScript, R, Python...)提供可擴展性或創建提前編譯的本機映像(native-image)。

更多關于GraalVM的信息可參考:此篇文章

GraalVM安裝

本文我們使用SDKMAN來安裝GraalVM。SDKMAN是一款用于在大多數基于Unix的系統上管理多個軟件開發套件的并行版本的工具。它提供了一個方便的命令行界面(CLI)和API,用于安裝,切換,刪除和列出候選人。它以前被稱為Groovy enVironment Manager (GVM),受到了非常有用的RVM和rbenv工具的啟發,該工具在Ruby社區中廣泛使用。

安裝SDKMAN

運行如下命令進行安裝:

$ curl -s "https://get.sdkman.io" | bash
$ source "$HOME/.sdkman/bin/sdkman-init.sh"	

運行如下命令,驗證是否已安裝ADKMAN:

$ sdk version

安裝GraalVM

運行如下命令:

$ sdk list java

可以看到SDKMAN列出了所支持的所有Java發行版

image-20200717142755813

我們找到GraalVM的發行版

image-20200717142840033

截至編寫本文時,GraalVM的最新版本為20.1.0.r11-grl,所以我們會安裝此版本。運行如下命令安裝GraalVM:

$ sdk install java 20.1.0.r11-grl

至此,GraalVM安裝完畢!我們可以運行如下命令來判斷GraalVM是否已安裝:

$ java -version

image-20200717143216643

創建項目

我們有多種方式創建Quarkus項目

使用Intellij IDEA創建Quarkus項目

點擊菜單欄File>New>Project... 創建新項目

image-20200717150609041

點擊Next,并填寫適當的信息,Next>Next...,創建完畢。

使用Maven命令行創建Quarkus項目

運行如下命令,創建Quarkus項目:

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

Quarkus并沒有類似Spring Boot、Helidon之類框架一樣的啟動類,我們需要通過運行Maven命令來啟動項目。

在IDEA控制臺運行如下命令來啟動項目:

./mvnw compile quarkus:dev

啟動成功!

image-20200717153314096

當然每次運行命令行會顯得不便,我們可以通過如下配置來配置項目快捷啟動:

image-20200717153444892

點擊左上角"+"圖標添加一個Maven配置如左邊欄,在右邊欄中的Command line中填入"compile quarkus:dev",點擊OK。

image-20200717153542033

此時可以點下下圖所示圖標來便捷啟動項目

image-20200717153914940

運行測試

打開項目中的測試類,看到如下代碼:

@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,只需在測試中添加以下內容:

@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變得更加本地化,不管是項目的體量方面還是資源消耗和運行效率方面都有顯著提升。

posted @ 2020-07-17 23:37  東溪陳姓少年  閱讀(77)  評論(0編輯  收藏
最新chease0ldman老人