微服務:Quarkus與Spring Boot

在容器時代(“ Docker時代”),Java仍然活着,不管是否努力奮鬥。 誰會贏:Spring Boot或Quarkus。

誰會贏? Spring Boot或Quarkus。

在容器時代(“ Docker時代”),Java仍然活着,不管是否努力奮鬥。 Java一直以其性能着稱,主要是因爲代碼和真實機器之間的抽象層,多平臺的成本(編寫一次,可以在任何地方運行-記住這一點嗎?),其中包含JVM。 -between(JVM:模擬真實計算機執行功能的軟件計算機)。

通過優銳課的java學習分享,如今,使用微服務架構可能不再有意義,也沒有任何優勢,而是爲始終在相同位置和平臺(Docker容器-Linux環境)上運行的東西構建多平臺(解釋)的東西。 可移植性現在不再那麼重要了(也許比以往任何時候都重要),那些額外的抽象級別並不重要。

話雖如此,讓我們在兩個備選方案之間進行簡單的原始比較,以在Java中生成微服務:非常知名的Spring Boot和不太熟悉的Quarkus。

對手
誰是 Quarkus?

一套適用於GraalVM和HotSpot的開源技術,可以編寫Java應用程序。 它提供(承諾)超快速的啓動時間和更低的內存佔用。 這使其非常適合容器和無服務器工作負載。 它使用Eclipse Microprofile(JAX-RS,CDI,JSON-P)(Java EE的子集)來構建Microservices。

GraalVM是通用的多語言虛擬機(JavaScript,Python,Ruby,R,Java,Scala,Kotlin)。 GraalVM(特別是Substrate VM)使提前(AOT)編譯成爲可能,將字節碼轉換爲本地機器代碼,從而產生可以本地執行的二進制文件。

請記住,並非所有功能都可以在本機執行中使用,因此AOT編譯有其侷限性。 請注意這句話(引用GraalVM團隊):

我們進行的主動靜態分析需要一個封閉世界的假設,這意味着在構建時必須知道運行時可訪問的所有類和所有字節碼。

因此,例如,反射和Java本機接口(JNI)將無法使用,至少是開箱即用的(需要一些額外的工作)。 你可以在此處的Native Image Java限制''文檔中找到限制列表。
誰是Spring Boot?

真? 好吧,只說一句話(隨意跳過):Spring Boot是建立在Spring框架之上的開源框架,它提供了一種更簡單的方法來構建,配置和運行基於Java Web的應用程序 。 使之成爲微服務的理想選擇。

準備-創建Docker映像
誇庫斯圖像

讓我們創建Quarkus應用程序,以便稍後將其包裝在Docker Image中。 基本上,我們將執行Quarkus入門指南中的相同操作。
使用Quarkus maven原型創建項目:

Dockerfile
mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR2:create \ 
DprojectGroupId=ujr.combat.quarkus \  
DprojectArtifactId=quarkus-echo \ 
DclassName="ujr.combat.quarkus.EchoResource" \
Dpath="/echo"

這將導致我們的項目結構如下:
請注意,這還創建了兩個示例Dockerfile(src / main / docker):一個用於普通的JVM App Image,另一個用於本機App Image。
在生成的代碼中,我們只需要更改一件事,在下面添加依賴項,因爲我們要生成JSON內容。

Dockerfile
<dependency> 
<groupId>io.quarkus</groupId> 
<artifactId>quarkus-resteasy-jsonb</artifactId> 
</dependency>

在整個RESTEasy項目實施過程中,Quarkus使用JAX-RS規範。
僅此而已,使用下一條命令,我們可以看到應用程序正在運行:

Dockerfile
mvn clean compile quarkus:dev

在這種模式下,我們還通過後臺編譯啓用了熱部署。 讓我們做一個簡單的測試來看看它:

Dockerfile
curl -sw "\n\n" http://localhost:8080/echo/ualter | jq .

現在我們看到它正在運行,讓我們創建Docker Image。

重要! 不要下載最新版本19.3.0,因爲它與Quarkus 1.0不兼容,也許會與Quarkus 1.1兼容。 現在,應該工作的版本是GraalVM 19.2.1,得到這個。
配置其環境變量起始路徑:

Dockerfile

At macOS will be: export

GRAALVM_HOME=/Users/ualter/Developer/quarkus/graalvm-ce-java8-19.2.1/Contents/Home/

然後在你的環境中爲GraalVM安裝本機映像:
Dockerfile

$GRAALVM_HOME/bin/gu install native-image

讓我們爲當前平臺生成本機版本(在這種情況下,將爲macOS生成本機可執行文件)。

Dockerfile

mvn package -Pnative

如果一切正常,我們可以在./target文件夾中找到一個名爲quarkus-echo-1.0-SNAPSHOT-runner的文件。 這是你的應用程序的可執行二進制文件,你可以運行以下命令來啓動它:./target/quarkus-echo-1.0-SNAPSHOT-runner。 無需使用JVM(普通的:java -cp app:lib / :etc App.jar),它是本機可執行二進制文件。

讓我們爲應用程序生成一個本機Docker鏡像。 該命令將創建一個本機映像,即帶有Linux本機可執行應用程序的Docker映像。 默認情況下,本機可執行文件是基於當前平臺(macOS)創建的,因爲我們知道此生成的可執行文件與將成爲容器(Linux)的平臺不是同一平臺,我們將指示Maven構建從中生成可執行文件 在容器內,生成本地docker鏡像:*

Dockerfile
mvn package -Pnative -Dquarkus.native.container-build=true

此時,請確保具有Docker容器運行時和可運行的環境。
該文件將是64位Linux可執行文件,因此自然地,此二進制文件不適用於我們的macOS,它是爲我們的Docker容器映像構建的。 因此,繼續前進...讓我們繼續進行Docker映像生成...

Dockerfile
docker build -t ujr/quarkus-echo -f src/main/docker/Dockerfile.native . 

Testing it...

  docker run -i --name quarkus-echo --rm -p 8081:8081 ujr/quarkus-echo

附帶說明,關於Docker映像大小:

最終的Docker映像爲115MB,但你可以使用無發行版的映像版本獲得一個很小的Docker映像。 非發行版映像僅包含你的應用程序及其運行時相關性,其他所有項(軟件包管理器,shell或在標準Linux發行版中常見的普通程序)都將被刪除。 我們的應用程序的Distroless映像大小爲42.3MB。 文件./src/main/docker/Dockerfile.native-distroless具有產生它的收據。

關於Distroless Images:“將運行時容器中的內容嚴格限制爲應用程序所需的內容是Google和其他在容器中使用了多年的技術巨頭的最佳實踐”
Spring啓動映像

在這一點上,可能每個人都知道如何生成普通的Spring Boot Docker映像,讓我們跳過細節吧? 只是一項重要的觀察,代碼是完全相同的。 更好的說法是幾乎一樣,因爲我們當然使用的是Spring框架註釋。 那是唯一的區別。

The Battle

讓我們啓動兩個容器,使其啓動並運行幾次,然後比較啓動時間和內存佔用量。

在此過程中,每個容器被創建並銷燬了10次。 後來,分析了他們的啓動時間及其內存佔用量。 下面顯示的數字是基於所有這些測試的平均結果。
啓動時間

顯然,當與可伸縮性和無服務器架構相關時,這方面可能會發揮重要作用。

關於無服務器架構,在此模型中,通常,臨時容器將由事件觸發以執行任務/功能。 在雲環境中,價格通常基於執行次數而不是先前購買的某些計算能力。 因此,此處的冷啓動可能會影響此類解決方案,因爲容器(通常)僅在執行任務時才處於活動狀態。

在“可伸縮性”中,很明顯,如果有必要突然進行橫向擴展,則啓動時間將定義直到容器完全準備就緒(啓動並運行)以響應所提出的加載方案之前所花費的時間。
這種情況(需要且快速)突然增加了多少,長時間的冷啓動情況可能更糟。

讓我們看看它們在啓動時間方面的表現:

好吧,你可能已經注意到,它是在啓動時間圖中插入的另一項經過測試的選項。 實際上,它與Quarkus應用程序完全相同,但是是使用JVM Docker Image(使用Dockerfile.jvm)生成的。 如我們所見,甚至使用Docker鏡像和JVM Quarkus應用程序的應用程序的啓動時間也比Spring Boot快。

不用說,顯然是獲勝者Quarkus Native應用程序,它是迄今爲止所有人中啓動速度最快的應用程序。

內存佔用
現在,讓我們檢查一下內存如何運行。 檢查每個容器應用程序在開始時需要消耗多少內存,以使其自身啓動並運行,以準備接收請求。

結論
總結一下所有事情,這就是我們在Linux Ubuntu中查看結果的結果:

看來Quarkus贏得了這兩輪比賽(啓動時間和內存佔用),以明顯的優勢戰勝了對手SpringBoot。

這可能使我們感到疑惑……也許是時候考慮一些真正的實驗室,經驗以及對Quarkus的一些嘗試了。 我們應該瞭解它在現實生活中的表現,它如何適合我們的業務場景以及最有用的東西。

但是,讓我們不要忘記其弊端,因爲我們已經在上面看到了JVM的某些功能在本機可執行二進制文件中無法(尚未/輕鬆)運行。 無論如何,可能是時候給Quarkus一個證明自己的機會了,特別是如果冷啓動的問題一直困擾着你。 如何在環境中使用一臺或兩臺裝有Quarkus的Pod(K8),如何看待一段時間後的性能會很有趣,不是嗎?

喜歡這篇文章的可以點個贊,歡迎大家留言評論,記得關注我,每天持續更新技術乾貨、職場趣事、海量面試資料等等
 > 如果你對java技術很感興趣也可以交流學習,共同學習進步。 
不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代

文章寫道這裏,歡迎完善交流。最後奉上近期整理出來的一套完整的java架構思維導圖,分享給大家對照知識點參考學習。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java乾貨

微服務:Quarkus與Spring Boot

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章