超音速亞原子 Java 框架來了,0.0015 秒內啟動一個應用,太快了。。

来源:https://www.cnblogs.com/javastack/archive/2023/11/15/17833960.html
-Advertisement-
Play Games

來源:juejin.cn/post/7023317351563001886 1、概述 SpringBoot框架不用多介紹,Java程式員想必都知道。相對來說熟悉Quarkus的人可能會少一些。Quarkus首頁放出的標語:超音速亞原子的Java(Supersonic Subatomic Java)。 ...


來源:juejin.cn/post/7023317351563001886

1、概述

SpringBoot框架不用多介紹,Java程式員想必都知道。相對來說熟悉Quarkus的人可能會少一些。Quarkus首頁放出的標語:超音速亞原子的Java(Supersonic Subatomic Java)。

它是為 OpenJDK HotSpot 和 GraalVM 量身定製的 Kubernetes Native Java 框架,基於同類最佳的 Java 庫和標準製作而成。Quarkus 的到來為開發 Linux 容器和 kubernetes 原生 Java 微服務帶來了一個創新平臺。

在本文中,我們將對這兩個 Java 框架 Spring Boot 和 Quarkus 進行簡單的比較。我們可以更好地瞭解它們之間的異同,以及一些特殊性。我們還會執行一些測試來衡量它們的性能。最後,我們會介紹一個開發人員如何從Spring轉換到Quarkus。

2、SpringBoot

Spring Boot 是一個基於 Java 的框架,專註於企業應用。它可以簡單使用所有 Spring 項目,並集成了許多開箱即用的功能,來幫助開發人員提高生產力。

Spring Boot減少了配置和樣板代碼的數量。此外,由於其約定優於配置方法,它根據依賴項自動註冊預設配置,大大縮短了 Java 應用程式的開發周期。

Spring Boot 基礎就不介紹了,推薦看這個實戰項目:

https://github.com/javastacks/spring-boot-best-practice

3、Quarkus

Quarkus 是另一個採用與上述 Spring Boot 類似方法的框架,但還有一個額外的優點,即以更快的啟動時間、更好的資源利用率和效率交付更小的工件(Supersonic、Subatomic)。

它針對雲、無伺服器和容器化環境進行了優化。儘管側重點略有不同, Quarkus 也能與最流行的 Java 框架很好地集成。

4、比較

如上所述,這兩個框架都與其他項目和框架有很好的集成。但是,它們的內部實現和架構是不同的。例如,Spring Boot 提供兩種類型的 Web 功能:阻塞(Servlets)和非阻塞(WebFlux)

另一方面,Quarkus 也提供這兩種方法,但與 Spring Boot 不同的是,它允許我們同時使用阻塞和非阻塞方法。此外,Quarkus 在其架構中嵌入了反應式編程方法。

為了在我們的比較中獲得更準確的數據,我們將使用兩個完全響應式的應用程式,這些應用程式使用 Spring WebFlux 和 Quarkus 響應式功能實現。

此外,Quarkus 項目中最重要的功能之一是能夠創建原生鏡像(Native Images,基於特定平臺的可執行二進位文件)。因此,我們還將在比較中包含兩個原生映像,但 Spring 的原生鏡像支持仍處於試驗階段。另外我們需要用到 GraalVM。

測試應用

我們的應用程式將實現三個 API:一個允許用戶創建郵政編碼,另一個用於查找特定郵政編碼的信息,最後按城市查詢郵政編碼。這些 API 是使用了前面提到的 Spring Boot 和 Quarkus 的反應式方法實現的,資料庫使用的是PostgreSQL。

我們的目標是創建一個比 HelloWorld 程式稍微複雜一些的樣常式序。當然,資料庫驅動和序列化框架等內容的實現會影響我們的比較結果。但是,大多數應用程式可能都會需要處理這些事情。

因此,比較的目的並不是為了證明哪個框架更好或更高效,而是分析研究這些特定實現的一個案例。

測試計劃

為了測試這兩種實現,我們將使用 JMeter 執行測試,並分析其測試報告。此外,我們將使用 VisualVM 在執行測試期間監控應用程式的資源利用率。

測試將運行 5 分鐘,會調用所有 API,從預熱期開始,然後增加併發用戶數,直到達到 1,500。我們將在前幾秒鐘開始填充資料庫,然後開始查詢,如下所示:

所有測試均在以下規格的機器上進行:

由於缺乏與其他後臺進程的隔離,最終結果可能不太理想,但正如前面提到的,我們無意對這兩個框架的性能進行廣泛而詳細的分析。

5、調查結果

對開發人員來說,這兩個項目的體驗都很棒,但值得一提的是 Spring Boot 有更好的文檔,在網上也可以找到更多資料。Quarkus 在這方面正在改進,但仍然有點落後。

在指標方面,我們有如下結果:

通過這個實驗,我們可以觀察到 Quarkus 在 JVM 和原生版本的啟動時間方面幾乎比 Spring Boot 快一倍。構建時間也快得多。在原生鏡像的情況下,構建耗時:9 分鐘(Quarkus)對 13 分鐘(Spring Boot),JVM 構建耗時:20 秒(Quarkus)對 39 秒(Spring Boot)。

Artifact(工件)的大小出現了同樣的情況,Quarkus 生成了更小的工件而再次領先。原生映像:75MB (Quarkus) 對 109MB (Spring Boot),以及JVM 版本:4KB (Quarkus) 對 26MB (Spring Boot)。

關於其他指標,結論並不是那麼顯而易見。因此,我們需要更深入地瞭解一下。

CPU

我們看到 JVM 版本在預熱階段開始時消耗更多的 CPU。之後CPU使用率趨於穩定,所有版本的消耗相對均等。

以下是 JVM 和 Native 版本中 Quarkus 的 CPU 消耗:

JVM 版的 Quarkus ↑↑↑

Native 版的 Quarkus ↑↑↑

記憶體

記憶體就更複雜了。首先,很明顯,兩個框架的 JVM 版本都為Heap(堆)預留了更多記憶體。儘管如此,Quarkus 從一開始就預留了較少的記憶體,啟動期間的記憶體利用率也是如此。

然後,查看測試期間的利用率,我們可以觀察到Native版本似乎不像 JVM 版本那樣有效或頻繁地回收記憶體。可以通過調整一些參數來改善這一點,在這個比較中,我們使用了預設參數,並沒有對 GC、JVM 選項或任何其他參數進行更改。

讓我們看一下記憶體使用圖:

Spring Boot JVM ↑↑↑

Quarkus JVM ↑↑↑

Spring Boot 原生 ↑↑↑

Quarkus 原生 ↑↑↑

在測試期間儘管Quarkus出現了更高的峰值,但確實消耗的記憶體資源更少。

響應時間

最後,關於響應時間和峰值使用的線程數,Spring Boot 似乎略微具有優勢。它能夠使用更少的線程處理相同的負載,同時還具有更好的響應時間。

Spring Boot Native 版本在這種情況下表現出更好的性能。但是讓我們看看每個版本的響應時間分佈:

Spring Boot JVM ↑↑↑

儘管有更多異常值,但 Spring Boot JVM 版本隨著時間的推移取得了最好的進展,這很可能是由於 JIT 編譯器優化[1]。

Quarkus JVM ↑↑↑

Spring Boot 原生 ↑↑↑

Quarkus 原生 ↑↑↑

Quarkus 在低資源利用率方面表現出強大的實力。然而,至少在這個實驗中,Spring Boot 在吞吐量和響應能力方面與Quarkus旗鼓相當。

這兩個框架都能夠處理所有請求而沒有任何錯誤。不僅如此,他們的表現也十分相似,並沒有太大的差距。

總而言之

考慮到所有因素,在實現 Java 應用程式時,這兩個框架都是很好的選擇。

Native程式速度快且資源消耗低,是無伺服器、短期(short-living)應用和資源消耗敏感環境的絕佳選擇。

另一方面,JVM 應用程式似乎有更多的開銷,但隨著時間的推移具有出色的穩定性和高吞吐量,非常適合健壯、長壽命的應用程式。

測試程式的代碼和用於測試它們的腳本可以在 GitHub 上找到[2]。

6、從 Spring 轉換到 Quarkus

隨著K8s的興起,對原生應用支持良好的Quarkus框架也越來越受到關註很多開發人員在考慮從 Spring 轉換到 Quarkus。然而,開發人員在開始評估新的框架時通常必須擱置他們現有的知識。

幸運的是, Quarkus 不一樣,因為它是由一群在 Java 技術方面具有深厚專業知識的工程師創建的。這包括 Spring API 相容性,創建Quarkus的工程師同時也是在 Red Hat Runtime 上為 Spring Boot 提供支持的工程師。

推薦一個開源免費的 Spring Boot 實戰項目:

https://github.com/javastacks/spring-boot-best-practice

7、我是 Spring 開發者,為什麼要選Quarkus?

越來越明顯的是,容器化,尤其是 Kubernetes,正在迫使人們重新評估 Java ,用於開發雲原生應用程式。Kubernetes 是一種高度動態的共用基礎設施。由於集群中托管的應用程式數量的增長以及對應用程式生命周期變化的響應能力的提高(例如重新部署和向上/向下擴展),基礎設施的投入變得更加划算。

傳統的 Java 雲原生運行時在現有的棧上增加了新的分層,而沒有真正重新考慮底層。這導致更大的記憶體消耗和更慢的啟動時間,以至於現在很多公司為了從 Kubernetes 集群的大量投資中獲得更多價值,願意放棄他們深厚的 Java 專業知識,為 Go 和 Node.js 重新培養人才和開發工具。

傳統雲原生 Java 棧 ↑↑↑

這正是 Quarkus 解決的問題。Quarkus 針對記憶體使用率和快速啟動時間進行了優化。與其他雲原生 Java 棧相比,在 JVM 上運行的 Quarkus 應用可以在相同數量的RAM中提供近兩倍的應用程式實例,並且當打包為原生二進位文件時,實例數量增加了 7 倍。

這不僅僅是使用 SubstrateVM[3](GraalVM 的一個特性)簡單地編譯為原生二進位文件。

Quarkus 專為 Kubernetes 的基礎設施優化了傳統的 “高度動態”框架,從而降低了記憶體利用率並加快了初始啟動速度,結果是運行時效率的顯著提高。這些經過優化且文檔齊全的框架稱為“擴展”,由同類最佳的標準 API 組成。

運行時效率 ↑↑↑

Quarkus 棧 ↑↑↑

我司為什麼要從 Spring Boot 遷移到 Quarkus?

以我們公司為例,我司的舊系統基於 Spring 和 Tomcat。當我們維護和部署時,這個傳統的框架給我們帶來了一些困擾,基於以下原因我們決定遷移到Quarkus:

  • 記憶體和 CPU 消耗:對於正在執行的操作,Spring 和 Tomcat 框架在應用的主要目的之外使用了過多的資源。
  • 預熱時間:Spring 應用程式可能需要 10-20 秒的時間才能啟動,之後應用程式才可以開始預熱。
  • 無用的代碼:作為開發人員,我們都討厭樣板代碼(boilerplate code)。
  • 測試:Quarkus 讓編寫單元測試和集成測試變得非常容易。只需在那裡打一個@QuarkusTest 註釋,它實際上會啟動整個應用程式以運行您的測試。
  • 橫向擴展(Scale-out) vs. 縱向擴展(Scale-up):每個應用程式越小(資源方面),我們可以添加的越多。在這裡橫向可擴展性勝出。
  • 學習曲線:Quarkus 的線上文檔非常簡單易懂。

8、Spring 開發者可以活用哪些現有知識?

Quarkus 的 Spring API 相容性包括 Spring DI、Spring Web 和 Spring Data JPA。同時也在計劃其他 Spring API,如 Spring Security 和 Spring Config。在 JVM 上運行時,Quarkus 應用程式幾乎可以利用任何 Java 庫。只要不使用 Java 反射,這些Java庫就可以編譯為原生。

例如,受 Spring 開發人員歡迎的 Lombok 庫就可以原生編譯。需要明確的是,Quarkus 中的 Spring API 相容性並非為了作為一個完整的 Spring 平臺來重新托管現有的 Spring 應用程式。目的是為了讓基於 Quarkus 開發新應用程式成為一種自然的入門體驗。結合預先優化的擴展,Quarkus 為微服務開發提供了大量的功能。很多開發人員已成功將 Spring 應用程式遷移到 Quarkus。

Spring 框架本質上是高度動態的。為瞭解決這個問題,Quarkus的Spring 相容性擴展將 Spring API 映射到現有擴展中的 API,這些擴展已經針對快速啟動、降低記憶體利用率和原生編譯進行了優化,例如 RestEasy 和 CDI。此外,Quarkus的Spring 相容性擴展不使用 Spring 應用程式上下文。由於這些原因,嘗試使用額外的 Spring 庫可能不會奏效。

推薦一個開源免費的 Spring Boot 實戰項目:

https://github.com/javastacks/spring-boot-best-practice

Quarkus Spring Web Example

import java.util.List;
import java.util.Optional;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/person")
public class PersonController {
    @GetMapping(path = "/greet/{id}", produces = "text/plain")
    public String greetPerson(@PathVariable(name = "id") long id) {
        String name="";
        // ...
        return name;
    }

    @GetMapping(produces = "application/json")
    public Iterable<Person> findAll() {
        return personRepository.findAll();
    }

Quarkus Spring Repository Example

package org.acme.springmp;

import java.util.List;
import org.springframework.data.repository.CrudRepository;

public interface PersonRepository extends CrudRepository<Person, Long> {
    List<Person> findByAge(int age);
}

Quarkus Spring Service + MicroProfile Fault Tolerance Example

import org.eclipse.microprofile.faulttolerance.Fallback;
import org.eclipse.microprofile.faulttolerance.Timeout;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service                                            // Spring
public class PersonService {

    @Autowired                                      // Spring
    @RestClient                                     // MicroProfile
    SalutationMicroProfileRestClient salutationRestClient;

    @Value("${fallbackSalutation}")                 // Spring
    String fallbackSalutation;

    @CircuitBreaker(delay=5000, failureRatio=.5)    // MicroProfile
    @Fallback(fallbackMethod = "salutationFallback")// MicroProfile
    public String getSalutation() {
        return salutationRestClient.getSalutation();
    }

9、對Spring開發者有額外的好處嗎?

除了提高記憶體利用率和啟動時間外,Quarkus 還為 Spring 開發人員提供了以下好處:

  • 功能即服務 (FaaS) 。當編譯為原生二進位文件時,Quarkus 應用程式可以在 0.0015 秒內啟動,從而可以將現有的 Spring 和 Java API 知識與 FaaS 功能結合使用。(Azure、AWS Lambda)
  • 實時編碼。從“Hello World”示例應用程式開始,然後將其轉換為複雜的微服務,而無需重新啟動應用程式。只需保存並重新載入瀏覽器即可查看沿途的變化。Quarkus 實時編碼“開箱即用”,與 IDE 無關。
  • 支持反應式和命令式模型。 Quarkus 有一個反應式核心,支持傳統的命令式模型、反應式模型,或在同一應用程式中同時支持兩者。
  • 早期檢測依賴註入錯誤。 Quarkus 在編譯期間而不是在運行時捕獲依賴項註入錯誤。
  • 最佳框架和標準的結合。Quarkus 在同一應用程式中支持 Spring API 相容性、Eclipse Vert.x、MicroProfile(JAX-RS、CDI 等)、反應式流和消息傳遞等,可以在一個項目中同時使用 Spring 和 MicroProfile API。

10、Spring開發者如何開始學習Quarkus?

推薦的步驟包括:

  • 參看入門指南[4]作為 Quarkus 的一般介紹。
  • 參看 Spring DI[5]、Spring Web[6] 和 Spring Data JPA[7] 的指南。
  • 使用 code.quarkus.io[8] 創建一個新應用。

參考資料:

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 介面數據類型與表單提交數據類型,在大多數情況下,大部分屬性的類型是相同的,但很少能做到完全統一。我在之前的工作中經常為了方便,直接將介面數據類型復用為表單內數據類型,在遇到屬性類型不一致的情況時會使用any強制忽略類型錯誤。後來經過自省與思考,這種工作模式會引起各種隱藏bug,一定有更好的工程解決方... ...
  • 1、提示 由於國內註冊 https://api.openai.com 比較麻煩,直接購買的第三方介面和key 淘寶購買,幾塊錢1個月 3、自己娛樂夠用 2、前端框架 Vant 移動端使用 axios 3、創建攔截器,api/request.js /* * @Descripttion: 文件說明 * ...
  • 跨域這兩個字就像一塊狗皮膏藥一樣黏在每一個前端開發者身上,無論你在工作上或者面試中無可避免會遇到這個問題。如果在網上搜索跨域問題,會出現許許多多方案,這些方案有好有壞,但是對於闡述跨域的原理和在什麼情況下需要用什麼方案,缺少系統性的說明。大家在工作中可能因為大佬們已經配置好了,不會產生跨域,但是作為... ...
  • 我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 本文作者:奇銘 前言 目前數棧的多個產品中都支持線上編輯 SQL 來生成對應的任務。比如離線開發產品和實時開發產品。在使用 MonacoEditor 為編輯器的基礎上, ...
  • 需求落地分散式應用服務 將需求轉化為分散式應用服務的過程可以按照以下步驟進行: 理解需求:首先,你需要仔細閱讀和理解業務需求。與相關的利益相關者(如業務分析師、產品經理等)進行溝通,確保你對需求的理解是準確的。 設計架構:根據需求,設計一個適合的分散式應用架構。這包括確定應用的組件和模塊,以及它們之 ...
  • 本文介紹了結構型設計模式中的代理設計模式,講解了靜態代理、JDK的動態代理和cglib的動態代理,並用代碼進行演示。 ...
  • 故事很老套。。就一堆漂亮姑娘毫無道理的、莫名其妙的往死里貼“我”,很煩人~只要略施小計,就能將她們攬入懷中,非常魔幻。 因為這游戲不只是火,同時還口碑超高。《美女包圍》剛發售時的好評率是83%,火了後評價不降反升,現在是恐怖的93%。 性感辣媽林樂清 —— 王星辰(身材姣好,入得廳堂下得廚房,娶妻當 ...
  • 定義 最短路樹:以圖上一個點為根節點,刪去部分邊後所形成的樹,樹的邊權滿足任意一點與根結點的路徑長度等於圖上兩點的最短路徑長度。 求法 可以採用 dij 求解。 每次更新 \(dis_v\) 時,記錄每個點最後一次用來更新的邊,即為最短路樹。 核心代碼如下,時間複雜度為 dij 的時間複雜度即 \( ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...