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

使用Spring Boot 3.2虛擬線程搭建靜態(tài)文件服務(wù)器

請(qǐng)問(wèn)6455支持對(duì)16位flash操作嗎?
Spring Boot從零入門1 詳述
Spring Boot特有的實(shí)踐
強(qiáng)大的Spring Boot 3.0要來(lái)了
用這4招 優(yōu)雅的實(shí)現(xiàn)Spring Boot異步線程間數(shù)據(jù)傳遞
Spring Boot Web相關(guān)的基礎(chǔ)知識(shí)
Spring Boot Actuator快速入門
Spring Boot啟動(dòng) Eureka流程

Spring Boot的啟動(dòng)原理

Spring Boot 的設(shè)計(jì)目標(biāo)

評(píng)論