早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错 。内容较长 , 抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读 。
测试场景作者采用了一个尽可能贴近现实操作的场景:
- 从授权头信息中提取JWT
- 验证JWT并从中提取用户的EmAIl
- 使用用户的Email去MySQL里执行查询
- 返回用户记录
- 带有虚拟线程的Spring Boot:这不是一个跑在传统物理线程上的Spring Boot应用,而是跑在虚拟线程上的 。这些轻量级线程简化了开发、维护和调试高吞吐量并发应用程序的复杂任务 。虽然虚拟线程仍然在底层操作系统线程上运行,但它们带来了显著的效率改进 。当虚拟线程遇到阻塞 I/O 操作时,JAVA 运行时会暂时挂起它 , 从而释放关联的操作系统线程来为其他虚拟线程提供服务 。这个优雅的解决方案优化了资源分配并增强了整体应用程序响应能力 。
- Spring Boot Webflux:Spring Boot WebFlux是Spring生态系统中的反应式编程框架,它利用Project Reactor库来实现非阻塞、事件驱动的编程 。所以,它特别适合需要高并发和低延迟的应用程序 。依靠反应式方法,它允许开发人员有效地处理大量并发请求,同时仍然提供与各种数据源和通信协议集成的灵活性 。
测试环境运行环境与工具
- 一台16G内存的macBook Pro M1
- Java 20
- Spring Boot 3.1.3
- 启用预览模式 , 以获得虚拟线程的强大能力
- 依赖的第三方库:jjwt、mysql-connector-java
- 测试工具:Bombardier
- 数据库:MySQL
- 在Bombardier中准备100000个JWT列表,用来从中随机选取JWT,并将其放入HTTP请求的授权信息中 。
- 在MySQL中创建一个users表,表结构如下:
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)
- 为users表准备100000条用户数据
server.port=3000spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=falsespring.datasource.username= testuserspring.datasource.password= testpwdspring.jpa.hibernate.ddl-auto= updatespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
User实体类(为了让文章让简洁一些 , 这里DD省略了getter和setter):@Entity@Table(name = "users")public class User {@Idprivate String email;private String first;private String last;private String city;private String county;private int age;}
应用主类:@SpringBootApplicationpublic class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}@Beanpublic TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {return protocolHandler -> {protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());};}}
提供CRUD操作的UserRepository:import org.springframework.data.repository.CrudRepository;import com.example.demo.User;public interface UserRepository extends CrudRepository<User, String> {}
提供API接口的UserController类:@RestControllerpublic class UserController {@AutowiredUserRepository 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();}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 公司用了六年的 SpringBoot 项目部署方案,稳得一批!
- 玩转Spring各种作用域Bean Scope及源码分析
- Spring Boot Starter的原理
- Spring 七种事务传播性介绍
- 基于深度学习的虚拟现实图像生成技术研究与应用
- 简易版的SpringBoot是如何实现的!!!
- Java 21 神仙特性:虚拟线程使用指南
- 响应式编程又变天了?看JDK21虚拟线程如何颠覆!
- Spring非常实用的技巧,你确定知道?
- 三分钟理解 Java 虚拟线程