成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringBoot3虛擬線程 & 反應式(WebFlux) & 傳統Tomcat線程池性能對比

開發 前端
啟用虛擬線程后,applicationTaskExecutor Bean 將成為配置為使用虛擬線程的 SimpleAsyncTaskExecutor。任何使用應用程序任務執行器的地方,如調用 @Async 方法時的 @EnableAsync、Spring MVC 的異步請求處理和 Spring WebFlux 的阻塞執行支持,現在都將使用虛擬線程。

環境:SpringBoot3.2.1 + JDK21

1. 簡介

從Spring Boot 3.2 支持虛擬線程。要使用虛擬線程,需要在 Java 21 上運行,并將屬性 spring.threads.virtual.enabled 設置為 true。

啟用虛擬線程后,Tomcat 和 Jetty 將使用虛擬線程處理請求。這意味著處理網絡請求的應用程序代碼(如控制器中的方法)將在虛擬線程上運行。

啟用虛擬線程后,applicationTaskExecutor Bean 將成為配置為使用虛擬線程的 SimpleAsyncTaskExecutor。任何使用應用程序任務執行器的地方,如調用 @Async 方法時的 @EnableAsync、Spring MVC 的異步請求處理和 Spring WebFlux 的阻塞執行支持,現在都將使用虛擬線程。

接下來將分別通過傳統阻塞Servlet技術、使用虛擬線程及使用反應式技術WebFlux來分別對比它們的性能。

2. 性能對比

使用虛擬線程 & 傳統Servlet都使用下面的接口:

@RestController
@RequestMapping("/task/default")
public class TaskDefaultController {


  @GetMapping("")
  public Object index() throws Exception {
    System.out.printf("before - %s%n", Thread.currentThread()) ;
    TimeUnit.MILLISECONDS.sleep(100) ;
    System.out.printf("after - %s%n", Thread.currentThread()) ;
    return "task - default..." ;
  }
}

先測試下啟用虛擬線程執行情況。

配置:

spring:
  threads:
    virtual:
      enabled: true

控制臺輸出:

before - VirtualThread[#42,tomcat-handler-0]/runnable@ForkJoinPool-1-worker-1
after - VirtualThread[#42,tomcat-handler-0]/runnable@ForkJoinPool-1-worker-1

使用的是虛擬線程。

2.1 傳統Tomcat線程池方式

配置線程池,如果不配置使用默認的最大線程200,整體的吞吐量將在2200作用。

server:
  tomcat:
    threads:
      min-spare: 500
      max: 1000

初始啟動服務后,內存,CPU占用情況;默認啟動后線程個數與上面配置一致。

圖片圖片

使用jmeter測試,配置如下:

圖片圖片

使用500個線程,循環200次,整體做100000次壓測。后續的測試都會基于該配置進行。

圖片圖片

吞吐量為:4696

內存,CPU占用情況

圖片圖片

2.2 使用虛擬線程

首先開啟虛擬線程

spring:
  threads:
    virtual:
      enabled: true

初始啟動服務后,內存,CPU占用情況

圖片圖片

jmeter測試情況如下:

圖片圖片

吞吐量為:4677,與上面的阻塞Servlet基本差不多。但傳統Tomcat線程池方式需要更多的線程才能達到這一值。

圖片圖片

整個過程內存使用情況,虛擬線程要比傳統Tomcat線程池方式占用的多。

JDK 的虛擬線程調度器是一個工作偷取 ForkJoinPool,以先進先出(FIFO)模式運行。調度器的并行性是指可用來調度虛擬線程的平臺線程數。默認情況下,它等于可用處理器的數量,但可以通過系統屬性 jdk.virtualThreadScheduler.parallelism 進行調整。ForkJoinPool 與普通池不同,普通池用于并行流的實現,并以后進先出模式運行。

調整數量再進行測試,設置JVM參數

-Djdk.virtualThreadScheduler.parallelism=100 -Djdk.virtualThreadScheduler.maxPoolSize=100

設置100個平臺線程來調用虛擬線程。

啟動服務后,線程,內存使用情況。

圖片圖片

jmeter測試結果如下:

圖片圖片

與調整前沒什么區別,反而是增加了應用的線程數量。

2.3 反應式WebFlux

引入依賴

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

基于webflux,我們需要重新編寫接口測試。

@RestController
@RequestMapping("/task/reactor")
public class ReactorController {


  @GetMapping("")
  public Object index() throws Exception {
    // 與上面2種方式不同,reactor方式則需要使用delayElement方式來模擬耗時任務
    return Mono.just("task - reactor...").delayElement(Duration.ofMillis(100)) ;
  }
}

初始啟動服務后,內存,CPU占用情況。

圖片圖片

jmeter測試情況如下:

圖片圖片

吞吐量為:4659,與上面的測試結果基本一致。

圖片圖片

內存使用情況要比前面幾種方式占用都少。同時通過jmeter測試結果也能發現,MAX請求的最大響應時間webflux是最小的,Std.Dev:所有請求響應時間的標準差也是最小的(該值越小,平均值越可靠)。

根據測試結果,虛擬線程與webflux誰更勝一籌還不夠清晰,接下來我們結合數據庫操作進行測試。

3. 基于數據庫測試

數據庫數據準備了600w的數據。

圖片圖片

3.1 傳統Tomcat線程池方式

基于JPA進行數據庫的操作

@Entity
@Table(name = "t_user")
public class User {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer uid ;
  private String name ;
}

Repository接口

public interface UserRepository extends JpaRepository<User, Integer> {
}

Controller測試接口

@RestController
@RequestMapping("/users")
public class UserController {


  @Resource
  private UserRepository ur ;
  
  @GetMapping("/count")
  public User count() {
    return ur.findById(5800000).orElse(null) ;
  }
  
}

測試結果:

圖片圖片

3.2 使用虛擬線程

記得開啟虛擬線程,測試結果如下:

圖片圖片

3.3 反應式WebFlux

需要引入如下依賴

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
  <groupId>com.github.jasync-sql</groupId>
  <artifactId>jasync-r2dbc-mysql</artifactId>
  <version>2.1.24</version>
</dependency>

配置

spring:
  r2dbc:
    url: r2dbc:mysql://localhost:3306/batch?serverZnotallow=GMT%2B8&sslMode=DISABLED
    username: root
    password: xxxooo
    pool:
      initialSize: 100
      maxSize: 100
      max-acquire-time: 30s 
      max-idle-time: 30m

實體定義,這里的注解與jpa不一樣

@Table("t_user")
public class User {
  
  @Id
  private Integer uid ;
  private String name ;
}

Repository定義

public interface UserR2DBCRepository extends ReactiveCrudRepository<User, Integer> {
}

Controller接口

@RestController
@RequestMapping("/r2dbc")
public class UserR2DBCController {


  @Resource
  private UserR2DBCRepository ur ;
  
  @GetMapping("/users")
  public Mono<User> count() {
    return ur.findById(5800000)  ;
  }
  
}

測試結果

圖片圖片

根據測試結果來,webflux的整體性能遠遠高于虛擬線程及傳統tomcat線程池的方式。

以上是本篇文章全部內容,希望對你有幫助。

完畢!!!

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2022-03-29 07:32:38

R2DBC數據庫反應式

2024-05-10 08:10:05

Spring虛擬線程JDK

2024-01-10 09:59:19

虛擬線程信息

2024-10-07 08:40:56

Spring應用程序Java

2021-01-28 11:17:49

Python爬蟲單線程

2023-10-13 08:20:02

Spring線程池id

2023-09-21 08:01:27

SpringR2DBC實現數據庫

2019-12-27 09:09:42

Tomcat線程池JDK

2022-08-15 09:00:00

JavaScript前端架構

2023-11-27 00:46:39

裸機虛擬機

2024-10-06 14:37:52

2014-06-05 10:22:06

Tomcat 7

2021-06-17 06:57:10

SpringBoot線程池設置

2021-12-05 23:37:21

Java9異步編程

2021-08-20 08:22:12

Tomcat原生線程池

2023-08-07 14:28:07

SpringBoot工具

2023-11-06 18:37:23

虛擬線程編寫

2013-11-08 10:59:17

Hadoop虛擬化VMware vSph

2023-12-26 08:15:11

反應式遠程接口

2021-07-15 11:16:31

Spring WebWebFlux架構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品欧美一区二区在线观看视频 | 成人av在线播放 | 亚洲精品国产第一综合99久久 | 国产视频导航 | 成人免费观看视频 | 91久久夜色精品国产网站 | 久久久精品一区二区 | 欧美精品中文字幕久久二区 | 一级黄色片在线看 | 在线一区二区三区 | 国产精品一区二区在线 | 中文字幕在线一区二区三区 | www.久久国产精品 | 一级免费看 | 日韩欧美国产精品一区二区 | 美女黄网 | 你懂的国产 | 日韩av美女电影 | 亚洲黄色一级 | 成人av一区二区三区 | www.亚洲一区二区三区 | 亚洲福利一区二区 | 毛片久久久 | 人人人人干 | 亚洲欧洲色视频 | 一级黄色淫片 | 91九色在线观看 | 一区二区三区免费观看 | 日韩成人免费中文字幕 | 日韩三级在线观看 | 我爱操 | 亚洲欧美视频 | 欧美精品1区2区3区 精品国产欧美一区二区 | 一区中文字幕 | 欧美一区二区网站 | 亚洲欧美一区二区三区1000 | 成人精品国产 | 一区二区中文字幕 | 天堂一区在线 | 国产精品一区久久久 | 亚洲视频三|