MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

这篇具有很好参考价值的文章主要介绍了MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

之前已经分享过多篇关于Spring Boot中使用Java 21新特性虚拟线程的性能测试案例:

  • Spring Boot 3.2虚拟线程搭建静态文件服务器有多快?
  • Spring Boot 虚拟线程与Webflux在JWT验证和MySQL查询上的性能比较

早上看到群友问到一个关于虚拟线程遇到MySQL连接不兼容导致的性能问题:

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

这个问题确实之前就有看到过相关的评测,顺着个这个问题,重新把相关评测找出来,给大家分享一下。

以下内容主要参考文章:https://medium.com/deno-the-complete-reference/springboot-physical-vs-virtual-threads-vs-webflux-performance-comparison-for-jwt-verify-and-mysql-23d773b41ffd

评测案例

评测采用现实场景中的处理流程,具体如下:

  1. 从HTTP授权标头(authorization header)中提取 JWT
  2. 验证 JWT 并从中提取用户的电子邮件
  3. 使用提取到的电子邮件执行 MySQL 查询用户
  4. 返回用户记录

这个场景其实是Spring Boot 虚拟线程与Webflux在JWT验证和MySQL查询上的性能比较测试的后续。前文主要对比了虚拟线程和WebFlux的,但没有对比虚拟线程与物理线程的区别。所以,接下来的内容就是本文关心的重点:在物理线程和虚拟线程下,MySQL驱动是否有性能优化。

测试环境

  • Java 20(使用预览模式,开启虚拟线程)
  • Spring Boot 3.1.3
  • 依赖的第三方库:jjwt、mysql-connector-java

测试工具:Bombardier

采用了开源负载测试工具:Bombardier。在测试场景中预先创建 100,000 个 JWT 列表。

在测试期间,Bombardier 从该池中随机选择了JWT,并将它们包含在HTTP请求的Authorization标头中。

MySQL表结构与数据准备

User表结构如下:

mysql> desc users;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| email  | varchar(255) | NO   | PRI | NULL    |       |
| first  | varchar(255) | YES  |     | NULL    |       |
| last   | varchar(255) | YES  |     | NULL    |       |
| city   | varchar(255) | YES  |     | NULL    |       |
| county | varchar(255) | YES  |     | NULL    |       |
| age    | int          | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

准备大约10w条数据:

mysql> select count(*) from users;
+----------+
| count(*) |
+----------+
|    99999 |
+----------+
1 row in set (0.01 sec)

测试代码:使用物理线程

配置文件:

server.port=3000
spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username= dbuser
spring.datasource.password= dbpwd
spring.jpa.hibernate.ddl-auto= update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect

User实体定义:

@Entity
@Table(name = "users")
public class User {
  @Id
  private String email;

  private String first;

  private String last;

  private String city;

  private String county;

  private int age;

  // 省略了getter和setter
}

数据访问实现:

public interface UserRepository extends CrudRepository<User, String> {

}

API实现:

@RestController
public class UserController {

    @Autowired
    UserRepository userRepository;

    private SignatureAlgorithm sa = SignatureAlgorithm.HS256;
    private String jwtSecret = System.getenv("JWT_SECRET");

    @GetMapping("/")
    public User handleRequest(@RequestHeader(HttpHeaders.AUTHORIZATION) String authHdr) {
        String jwtString = authHdr.replace("Bearer","");
        Claims claims = Jwts.parser()
            .setSigningKey(jwtSecret.getBytes())
            .parseClaimsJws(jwtString).getBody();

        Optional<User> user = userRepository.findById((String)claims.get("email"));
        return user.get();
    }
}

应用主类:

@SpringBootApplication
public class UserApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

测试代码:使用虚拟线程

主要调整应用主类,其他一样,具体修改如下:

@SpringBootApplication
public class UserApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }

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

测试代码:使用WebFlux

server.port=3000
spring.r2dbc.url=r2dbc:mysql://localhost:3306/testdb?allowPublicKeyRetrieval=true&ssl=false
spring.r2dbc.username=dbuser
spring.r2dbc.password=dbpwd
spring.r2dbc.pool.initial-size=10
spring.r2dbc.pool.max-size=10
@Table(name = "users")
public class User {
  @Id
  private String email;

  private String first;

  private String last;

  private String city;

  private String county;

  private int age;

  // 省略getter、setter和构造函数
}

数据访问实现:

public interface UserRepository extends R2dbcRepository<User, String> {

}

业务逻辑实现:

@Service
public class UserService {

  @Autowired
  UserRepository userRepository;

  public Mono<User> findById(String id) {
    return userRepository.findById(id);
  }
}

API实现:

@RestController
@RequestMapping("/")
public class UserController {
  @Autowired
  UserService userService;

  private SignatureAlgorithm sa = SignatureAlgorithm.HS256;
  private String jwtSecret = System.getenv("JWT_SECRET");

  @GetMapping("/")
  @ResponseStatus(HttpStatus.OK)
  public Mono<User> getUserById(@RequestHeader(HttpHeaders.AUTHORIZATION) String authHdr) {
    String jwtString = authHdr.replace("Bearer","");
    Claims claims = Jwts.parser()
        .setSigningKey(jwtSecret.getBytes())
        .parseClaimsJws(jwtString).getBody();
    return userService.findById((String)claims.get("email"));
  }
}

应用主类:

@EnableWebFlux
@SpringBootApplication
public class UserApplication {

  public static void main(String[] args) {
    SpringApplication.run(UserApplication.class, args);
  }

}

测试结果

每次测试都包含 100 万个请求,分别评估了它们在不同并发(50、100、300)水平下的性能。下面是结果展示:

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差

分析总结

在这个测试案例中使用了MySQL驱动,虚拟线程的实现方式性能最差,WebFlux依然保持领先。所以,主要原因在于这个MySQL的驱动对虚拟线程不友好。如果涉及到数据库访问的情况下,需要寻找对虚拟线程支持最佳的驱动程序。另外,该测试使用的是Java 20和Spring Boot 3.1。对于Java 21和Spring Boot 3.2建议读者在使用的时候自行评估。

最后,对于MySQL驱动对虚拟线程支持好的,欢迎留言区推荐一下。如果您学习过程中如遇困难?可以加入我们超高质量的Spring技术交流群,参与交流与讨论,更好的学习与进步!更多Spring Boot教程可以点击直达!,欢迎收藏与转发支持!

欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源文章来源地址https://www.toymoban.com/news/detail-802900.html

到了这里,关于MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Jpa与Druid线程池及Spring Boot整合(一): spring-boot-starter-data-jpa 搭建持久层

                          Jpa与Druid线程池及Spring Boot整合(一) Jpa与Druid线程池及Spring Boot整合(二):几个坑 附录官网文档:core.domain-events域事件 docker实战(一):centos7 yum安装docker docker实战(二):基础命令篇 docker实战(三):docker网络模式(超详细) docker实战(四):docker架构原理 docker实战(五

    2024年02月13日
    浏览(54)
  • Jpa与Druid线程池及Spring Boot整合(二): spring-boot-starter-data-jpa 踏坑异常处理方案

                         docker实战(一):centos7 yum安装docker docker实战(二):基础命令篇 docker实战(三):docker网络模式(超详细) docker实战(四):docker架构原理 docker实战(五):docker镜像及仓库配置 docker实战(六):docker 网络及数据卷设置 docker实战(七):docker 性质及版本选择 认知升维: 道、法、

    2024年02月13日
    浏览(61)
  • Spring Boot中内置Tomcat最大连接数、线程数与等待数 实践调优

    在 Spring Boot 框架中,我们使用最多的是Tomcat,这是 Spring Boot 默认的容器技术,而且是内嵌式的 Tomcat。Tomcat 是 Apache 基金下的一个轻量级的Servlet 容 器 , 支 持 Servlet 和 JSP 。Tomcat服务器本身具有Web服务器的功能,可以作为独立的Web服务器来使用。 Spring Boot 能支持的最大并发

    2024年02月12日
    浏览(44)
  • 从零到Kafka:万字带你体验Spring Boot整合消息驱动的奇妙之旅

    主页传送门:📀 传送 Spring boot : | 基于Spring的开源框架,用于简化新Spring应用的初始搭建以及开发过程 特性: | 快速开发、轻量级、无代码生成和独立运行等特性 优势: | 简化配置,提供自动配置,减少开发时间 应用场景: | 适用于微服务架构、云原生应用等场景 环境

    2024年02月05日
    浏览(43)
  • Spring Boot中加@Async和不加@Async有什么区别?设置核心线程数、设置最大线程数、设置队列容量是什么意思?直接在yml中配置线程池

    在 Spring 中,@Async 注解用于将方法标记为异步执行的方法。当使用 @Async 注解时,该方法将在单独的线程中执行,而不会阻塞当前线程。这使得方法可以在后台执行,而不会影响主线程的执行。 在您提供的代码示例中,a1() 和 a2() 方法都被标记为 @Async,意味着它们将以异步方

    2024年01月19日
    浏览(41)
  • spring boot+MySQL实现学习平台

    本次设计任务是要设计一个学习平台,通过这个系统能够满足学习信息的管理及学生和教师的学习管理功能。系统的主要功能包括首页,个人中心,学生管理,教师管理,课程信息管理,类型管理,作业信息管理,资料信息管理,签到信息管理,成绩统计管理,学生作业管理

    2024年02月13日
    浏览(42)
  • [Spring Boot + MyBatis + MySQL框架搭建]

    目录 🐉创建一个新的Spring Boot项目 🐉配置文件 🐉application.properties配置: 🐉创建实体类 🐉创建Mapper接口 🐉创建Mapper XML文件 🐉创建Service和Controller 🐉创建一个Controller类,用于处理HTTP请求和响应。在src/main/java目录下创建一个名为“com.example.demo.controller”的包,并在其中

    2024年02月11日
    浏览(43)
  • Spring Boot MySQL数据库的使用

    目录 简介Spring Boot Spring Boot的优点 Spring Boot连接数据库 1.添加依赖 1.2开启连接数据库 1.2.1 如果没有开启数据库运行程序的时候会出现这样的报错这就是没有连接数据库,所以我们开启数据库即可使用。 1.2.2 我的名字是MySQL110所以一会用命令字符开启数据库的时候用的就是这

    2024年04月10日
    浏览(45)
  • Docker 部署 Spring Boot 项目(含 MySQL + Redis )

    注意事项:如果需要将 Spring Boot 项目的日志文件挂载到本地,则在打包前需要先在 yml 进行如下配置: 这里的 info 指的是日志等级,可以根据需要进行修改,日志等级主要有以下几种: trace :最低的日志级别,用于记录非常详细的信息,通常仅在诊断问题时使用。 debug :用

    2024年01月21日
    浏览(46)
  • spring boot+MySQL实现班级综合测评管理系统

    随着电子技术的普及和快速发展,线上管理系统被广泛的使用,有很多事业单位和商业机构都在实现电子信息化管理,班级综合测评管理也不例外,由比较传统的人工管理转向了电子化、信息化、系统化的管理。 传统的班级综合测评管理系统,一开始都是手工记录,然后将手

    2024年02月15日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包