最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

在 Spring 6 中使用虛擬線程

2023-08-27 20:01 作者:zepherywen  | 我要投稿

一、簡介

在這個簡短的教程中,我們將了解如何在 Spring Boot 應(yīng)用程序中利用虛擬線程的強(qiáng)大功能。

虛擬線程是Java 19 的預(yù)覽功能,這意味著它們將在未來 12 個月內(nèi)包含在官方 JDK 版本中。Spring 6 版本最初由 Project Loom 引入,為開發(fā)人員提供了開始嘗試這一出色功能的選項(xiàng)。

首先,我們將看到“平臺線程”和“虛擬線程”之間的主要區(qū)別。接下來,我們將使用虛擬線程從頭開始構(gòu)建一個 Spring-Boot 應(yīng)用程序。最后,我們將創(chuàng)建一個小型測試套件,以查看簡單 Web 應(yīng)用程序吞吐量的最終改進(jìn)。

二、 虛擬線程與平臺線程

主要區(qū)別在于虛擬線程在其操作周期中不依賴于操作系統(tǒng)線程:它們與硬件解耦,因此有了“虛擬”這個詞。這種解耦是由 JVM 提供的抽象層實(shí)現(xiàn)的。

對于本教程來說,必須了解虛擬線程的運(yùn)行成本遠(yuǎn)低于平臺線程。它們消耗的分配內(nèi)存量要少得多。這就是為什么可以創(chuàng)建數(shù)百萬個虛擬線程而不會出現(xiàn)內(nèi)存不足問題,而不是使用標(biāo)準(zhǔn)平臺(或內(nèi)核)線程創(chuàng)建幾百個虛擬線程。

從理論上講,這賦予了開發(fā)人員一種超能力:無需依賴異步代碼即可管理高度可擴(kuò)展的應(yīng)用程序。

三、在Spring 6中使用虛擬線程

從 Spring Framework 6(和 Spring Boot 3)開始,虛擬線程功能正式公開,但虛擬線程是Java 19 的預(yù)覽功能。這意味著我們需要告訴 JVM 我們要在應(yīng)用程序中啟用它們。由于我們使用 Maven 來構(gòu)建應(yīng)用程序,因此我們希望確保在 pom.xml 中包含以下代碼

<build>
? ?<plugins>
? ? ? ?<plugin>
? ? ? ? ? ?<groupId>org.apache.maven.plugins</groupId>
? ? ? ? ? ?<artifactId>maven-compiler-plugin</artifactId>
? ? ? ? ? ?<configuration>
? ? ? ? ? ? ? ?<source>19</source>
? ? ? ? ? ? ? ?<target>19</target>
? ? ? ? ? ? ? ?<compilerArgs>
? ? ? ? ? ? ? ? ? ?--enable-preview
? ? ? ? ? ? ? ?</compilerArgs>
? ? ? ? ? ?</configuration>
? ? ? ?</plugin>
? ?</plugins>
</build>

從 Java 的角度來看,要使用 Apache Tomcat 和虛擬線程,我們需要一個帶有幾個 bean 的簡單配置類:

@EnableAsync
@Configuration
@ConditionalOnProperty(
?value = "spring.thread-executor",
?havingValue = "virtual"
)
public class ThreadConfig {
? ?@Bean
? ?public AsyncTaskExecutor applicationTaskExecutor() {
? ? ? ?return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor());
? ?}

? ?@Bean
? ?public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
? ? ? ?return protocolHandler -> {
? ? ? ? ? ?protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
? ? ? ?};
? ?}
}

第一個 Spring Bean ApplicationTaskExecutor將取代標(biāo)準(zhǔn)的ApplicationTaskExecutor ,提供為每個任務(wù)啟動新虛擬線程的Executor。第二個 bean,名為ProtocolHandlerVirtualThreadExecutorCustomizer,將以相同的方式 自定義標(biāo)準(zhǔn)TomcatProtocolHandler 。我們還添加了注釋@ConditionalOnProperty,**以通過切換application.yaml文件中配置屬性的值來按需啟用虛擬線程:

spring:
? ?thread-executor: virtual
? ?//...

我們來測試一下Spring Boot應(yīng)用程序是否使用虛擬線程來處理Web請求調(diào)用。為此,我們需要構(gòu)建一個簡單的控制器來返回所需的信息:

@RestController
@RequestMapping("/thread")
public class ThreadController {
? ?@GetMapping("/name")
? ?public String getThreadName() {
? ? ? ?return Thread.currentThread().toString();
? ?}
}

Thread對象的toString ()方法將返回我們需要的所有信息:線程 ID、線程名稱、線程組和優(yōu)先級。讓我們通過一個curl請求來訪問這個端點(diǎn):

$ curl -s http://localhost:8080/thread/name
$ VirtualThread[#171]/runnable@ForkJoinPool-1-worker-4

正如我們所看到的,響應(yīng)明確表示我們正在使用虛擬線程來處理此 Web 請求。換句話說,Thread.currentThread()調(diào)用返回虛擬線程類的實(shí)例?,F(xiàn)在讓我們通過簡單但有效的負(fù)載測試來看看虛擬線程的有效性。

四、性能比較

對于此負(fù)載測試,我們將使用JMeter。這不是虛擬線程和標(biāo)準(zhǔn)線程之間的完整性能比較,而是我們可以使用不同參數(shù)構(gòu)建其他測試的起點(diǎn)。

在這種特殊的場景中,我們將調(diào)用Rest Controller中的一個端點(diǎn),該端點(diǎn)將簡單地讓執(zhí)行休眠一秒鐘,模擬復(fù)雜的異步任務(wù):

@RestController
@RequestMapping("/load")
public class LoadTestController {

? ?private static final Logger LOG = LoggerFactory.getLogger(LoadTestController.class);

? ?@GetMapping
? ?public void doSomething() throws InterruptedException {
? ? ? ?LOG.info("hey, I'm doing something");
? ? ? ?Thread.sleep(1000);
? ?}
}

請記住,由于@ConditionalOnProperty 注釋,我們只需更改 application.yaml 中變量的值即可在虛擬線程和標(biāo)準(zhǔn)線程之間切換

JMeter 測試將僅包含一個線程組,模擬 1000 個并發(fā)用戶訪問/load 端點(diǎn) 100 秒:


在本例中,采用這一新功能所帶來的性能提升是顯而易見的。讓我們比較不同實(shí)現(xiàn)的“響應(yīng)時間圖”。這是標(biāo)準(zhǔn)線程的響應(yīng)圖。我們可以看到,立即完成一次調(diào)用所需的時間達(dá)到 5000 毫秒:



發(fā)生這種情況是因?yàn)槠脚_線程是一種有限的資源,當(dāng)所有計劃的和池化的線程都忙時,Spring 應(yīng)用程序除了將請求擱置直到一個線程空閑之外別無選擇。

讓我們看看虛擬線程會發(fā)生什么:


正如我們所看到的,響應(yīng)穩(wěn)定在 1000 毫秒。虛擬線程在請求后立即創(chuàng)建和使用,因?yàn)閺馁Y源的角度來看它們非常便宜。在本例中,我們正在比較 spring 默認(rèn)固定標(biāo)準(zhǔn)線程池(默認(rèn)為 200)和 spring 默認(rèn)無界虛擬線程池的使用情況。

這種性能提升之所以可能,是因?yàn)閳鼍斑^于簡單,并且沒有考慮 Spring Boot 應(yīng)用程序可以執(zhí)行的全部操作。從底層操作系統(tǒng)基礎(chǔ)設(shè)施中采用這種抽象可能是有好處的,但并非在所有情況下都是如此。


在 Spring 6 中使用虛擬線程的評論 (共 條)

分享到微博請遵守國家法律
博爱县| 元江| 时尚| 九台市| 怀远县| 来宾市| 墨竹工卡县| 固安县| 兖州市| 额济纳旗| 马山县| 沧源| 鄂托克前旗| 灵台县| 凌海市| 民县| 台安县| 潮安县| 灵武市| 阜新市| 武鸣县| 池州市| 东阿县| 长海县| 隆林| 昌黎县| 定州市| 新巴尔虎左旗| 彭山县| 乌恰县| 延长县| 华宁县| 丹巴县| 蓝山县| 珠海市| 汝城县| 都昌县| 开远市| 株洲市| 云霄县| 平乡县|