來源:medium.com/@egorponomarev
Spring Boot 3.2 前幾日發布,讓我們用 Java 21、GraalVM 和虛擬線程來嘗試一下。
Spring Boot 3.2 支持:
Java 21
虛擬線程
原生鏡像(自 2022 年 11 月 Spring Boot 3.0 發布以來,Spring Boot 已在生產環境中支持 GraalVM 原生鏡像)
Java 21
我們期待 2023 年 9 月 19 日發布的 Java 21,Spring Boot 3.2 已經做到完全支持了。
正如所聲明的那樣,Java 21 提供了數千項性能、穩定性和安全性改進,包括平臺增強功能,可幫助開發人員提高生產力并推動整個組織的創新和增長。
虛擬線程
更重要的更新之一是虛擬線程,這是 Project Loom 提供的功能。我們不打算深入細節,官方 JEP 提供了很好的解釋:
GraalVM 和本機鏡像
GraalVM 是一種高性能 JDK,可以使用替代的即時 (JIT) 編譯器來加快 Java 和基于 JVM 的應用程序的性能。
Native Image 是一種提前將 Java 代碼編譯為獨立可執行文件(稱為本機映像)的技術。該可執行文件包括應用程序類、其依賴項中的類、運行時庫類以及來自 JDK 的靜態鏈接本機代碼。
它不在 Java VM 上運行,但包含來自不同運行時系統的必要組件,如內存管理、線程調度等。與 JVM 相比,生成的程序具有更快的啟動時間和更低的運行時內存開銷。
嘗鮮一下
讓我們從安裝 Java 21.0.1 graal 開始,最簡單的方法是使用SDKMAN 并將其指定為您機器的默認 Java 版本:
sdk install java 21.0.1-graal
sdk default java 21.0.1-graal
另一種安裝方法是手動下載
我們將使用Spring Initializr頁面創建一個新的Spring Boot項目,使用 Spring Boot 3.2.0、Java 21、Gradle-Groovy以及Spring Web和GraalVM本地支持依賴項。
要在 Spring Boot 3.2 中啟用虛擬線程,我們只需在 application.yml 或 application.properties 文件中設置一個屬性:
spring.threads.virtual.enabled:true
這個配置起到的作用:
Tomcat 將使用虛擬線程來處理 HTTP 請求。這意味著處理 Web 請求的應用程序代碼(例如控制器中的方法)將在虛擬線程上運行。
調用@Async方法時,Spring MVC 的異步請求處理和 Spring WebFlux 的阻塞執行支持現在將利用虛擬線程
標記有@Scheduled的方法將在虛擬線程上運行
因此,我們將嘗試使用這 3 個集成來實現虛擬線程。
此外,一些特定的集成將在虛擬線程上工作,例如 RabbitMQ/Kafka 監聽器,以及 Spring Data Redis/Apache pulsar 相關的集成。但這些集成超出了本文的范圍,有興趣的可以參考 Spring Boot 3.2 官方示例。
代碼
1.對于 Tomcat 傳入的 HTTP 請求,我們創建一個簡單的控制器:
@RestController @RequestMapping("/test") publicclassTestController{ privatestaticfinalLoggerlog=LoggerFactory.getLogger(TestController.class); @GetMapping publicvoidtest(){ log.info("Restcontrollermethodhasbeencalled{}",Thread.currentThread()); } }
2.異步任務
我們將在應用程序啟動時調用其“run”方法
@Component publicclassAsyncTaskExecutorService{ privatestaticfinalLoggerlog=LoggerFactory.getLogger(AsyncTaskExecutorService.class); @Async publicvoidrun(){ log.info("Asynctaskmethodhasbeencalled{}",Thread.currentThread()); } }
3.Scheduled 定時任務
一個簡單的方法,每 15 秒調用一次
@Component publicclassSchedulerService{ privatestaticfinalLoggerlog=LoggerFactory.getLogger(SchedulerService.class); @Scheduled(fixedDelayString="15000") publicvoidrun(){ log.info("Scheduledmethodhasbeencalled{}",Thread.currentThread()); } }
讓我們運行我們的應用程序:
./gradlewbootRun
并調用我們的端點
curl—位置—請求GET'localhost:8085/test'
我們得到什么:
StartingAppApplicationusingJava21.0.1withPID38126 StartedAppApplicationin1.131seconds(processrunningfor1.491) AsynctaskmethodhasbeencalledVirtualThread[#52,task-1]/runnable@ForkJoinPool-1-worker-5 ScheduledmethodhasbeencalledVirtualThread[#46,scheduling-1]/runnable@ForkJoinPool-1-worker-1 RestcontrollermethodhasbeencalledVirtualThread[#62,tomcat-handler-0]/runnable@ForkJoinPool-1-worker-1 ScheduledmethodhasbeencalledVirtualThread[#46,scheduling-1]/runnable@ForkJoinPool-1-worker-1
我們可以看到我們的方法的日志鏈接到公共 ForkJoinPool 線程池。
根據JEP:預期行為:
JDK 的虛擬線程調度程序是一個工作竊取的 ForkJoinPool,它以 FIFO 模式運行。調度程序的并行度是可用于調度虛擬線程的平臺線程的數量。
現在讓我們在 GraalVM 上運行它。
首先,我們需要構建一個 GraalVM 本機映像:(此命令可能需要幾分鐘)然后運行:(使用您的應用程序的名稱而不是“app”)
./gradlewnativeCompile ./build/native/nativeComplie/app
它也可以工作,并且啟動時間要快得多,這符合聲明的“與 JVM 相比,生成的程序具有更快的啟動時間和更低的運行時內存開銷”。
在這里您可以找到包含本文中使用的代碼的存儲庫來源
結論
Spring Boot 3.2 是我們一直在等待的東西!具有虛擬線程的本機映像允許我們編寫能夠提供與 Go 類似級別的性能和可擴展性的代碼,從而保持 JVM 的強大生態系統。
但是,您必須考慮到并非所有庫都已采用其代碼來與虛擬線程正常工作(在大多數情況下,它正在用 ReentrantLock 替換“synchronize”塊),您應該小心虛擬線程將使用的邏輯。
審核編輯:湯梓紅
-
JAVA
+關注
關注
20文章
2989瀏覽量
110357 -
線程
+關注
關注
0文章
508瀏覽量
20296 -
鏡像
+關注
關注
0文章
178瀏覽量
11267 -
SpringBoot
+關注
關注
0文章
175瀏覽量
408
原文標題:Spring Boot 3.2 正式發布,開箱即用的虛擬線程和 GraalVM,嘗鮮一下!
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
Spring Boot如何實現異步任務
Spring Boot虛擬線程和Webflux性能對比

使用Spring Boot 3.2虛擬線程搭建靜態文件服務器

請問6455支持對16位flash操作嗎?
Spring Boot從零入門1 詳述
Spring Boot特有的實踐
強大的Spring Boot 3.0要來了
用這4招 優雅的實現Spring Boot異步線程間數據傳遞
Spring Boot Web相關的基礎知識
Spring Boot Actuator快速入門
Spring Boot啟動 Eureka流程

Spring Boot的啟動原理

評論