來源: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
+關注
關注
19文章
2966瀏覽量
104702 -
線程
+關注
關注
0文章
504瀏覽量
19675 -
鏡像
+關注
關注
0文章
164瀏覽量
10707 -
SpringBoot
+關注
關注
0文章
173瀏覽量
177
原文標題:Spring Boot 3.2 正式發布,開箱即用的虛擬線程和 GraalVM,嘗鮮一下!
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論