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(src / main / docker):一個用於普通的JVM App Image,另一個用於本機App Image。在生成的程式碼中,我們只需要更改一件事,在下面新增依賴項,因為我們要生成JSON內容。
在整個RESTEasy專案實施過程中,Quarkus使用JAX-RS規範。僅此而已,使用下一條命令,我們可以看到應用程式正在執行:
在這種模式下,我們還通過後臺編譯啟用了熱部署。 讓我們做一個簡單的測試來看看它:
現在我們看到它正在執行,讓我們建立Docker Image。
重要! 不要下載最新版本19.3.0,因為它與Quarkus 1.0不相容,也許會與Quarkus 1.1相容。 現在,應該工作的版本是GraalVM 19.2.1,得到這個。配置其環境變數起始路徑:
Dockerfile
At macOS will be: export
然後在你的環境中為GraalVM安裝本機映像:Dockerfile
$GRAALVM_HOME/bin/gu install native-image
讓我們為當前平臺生成本機版本(在這種情況下,將為macOS生成本機可執行檔案)。
如果一切正常,我們可以在./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映象:*
此時,請確保具有Docker容器執行時和可執行的環境。該檔案將是64位Linux可執行檔案,因此自然地,此二進位制檔案不適用於我們的macOS,它是為我們的Docker容器映像構建的。 因此,繼續前進...讓我們繼續進行Docker映像生成...
Testing it...
附帶說明,關於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
一套適用於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(src / main / docker):一個用於普通的JVM App Image,另一個用於本機App Image。在生成的程式碼中,我們只需要更改一件事,在下面新增依賴項,因為我們要生成JSON內容。
在整個RESTEasy專案實施過程中,Quarkus使用JAX-RS規範。僅此而已,使用下一條命令,我們可以看到應用程式正在執行:
在這種模式下,我們還通過後臺編譯啟用了熱部署。 讓我們做一個簡單的測試來看看它:
現在我們看到它正在執行,讓我們建立Docker Image。
重要! 不要下載最新版本19.3.0,因為它與Quarkus 1.0不相容,也許會與Quarkus 1.1相容。 現在,應該工作的版本是GraalVM 19.2.1,得到這個。配置其環境變數起始路徑:
Dockerfile
At macOS will be: export
然後在你的環境中為GraalVM安裝本機映像:Dockerfile
$GRAALVM_HOME/bin/gu install native-image
讓我們為當前平臺生成本機版本(在這種情況下,將為macOS生成本機可執行檔案)。
Dockerfile
如果一切正常,我們可以在./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映象:*
此時,請確保具有Docker容器執行時和可執行的環境。該檔案將是64位Linux可執行檔案,因此自然地,此二進位制檔案不適用於我們的macOS,它是為我們的Docker容器映像構建的。 因此,繼續前進...讓我們繼續進行Docker映像生成...
Testing it...
附帶說明,關於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的某些功能在本機可執行二進位制檔案中無法(尚未/輕鬆)執行。