JDK8、JDK17、JDK21升级与性能对比
说明
笔者所在的公司还在用JDK8,但是随着JDK版本的不断迭代,2025年3月15号JDK24已经发布,随着JDK版本发布速度的加快,部分公司已经切换到JDK17或是JDK21,所以这次对JDK升级的过程以及压测性能做一个记录与对比。
事先声明:测试条件有限,结果仅供参考。
JDK升级
JDK8升级JDK17
1. IDEA修改项目设置,设置JDK版本
2. 修改项目SpringBoot + SpringCloud版本
项目采用多个子项目的结构
父POM
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<spring-boot.version>3.2.2</spring-boot.version>
<spring-cloud.version>2023.0.0</spring-cloud.version>
<micrometer-tracing.version>1.0.0</micrometer-tracing.version>
</properties>
特别注意boot需要使用parent引入,否则启动SpringCache会报错,目前只找到这种处理方法,感觉是BUG
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3. 更新部分Maven依赖版本
mybatisplus更新为Springboot3版本
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>
springfox改为springdoc
<!-- 官方建议是springdoc替代springfox-->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<version>2.3.0</version>
</dependency>
hutool改为6
<dependency>
<groupId>org.dromara.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>6.0.0-M10</version>
</dependency>
hibernate-validator版本更新
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
lombok版本更新
<dependency>
<artifactId>lombok</artifactId>
<groupId>org.projectlombok</groupId>
<version>1.18.30</version>
</dependency>
Sleuth
<!-- Sleuth with Brave tracer implementation -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
4. 代码更新
javax.改为jakarta.
import javax.annotation.Resource;
to
import jakarta.annotation.Resource;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;
HandlerInterceptorAdapter被删除了,改为接口HandlerInterceptor
public class RioCheckInterceptor extends HandlerInterceptorAdapter {
public class RioCheckInterceptor implements HandlerInterceptor {
5. Maven插件更新
web项目POM
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<mainClass>com.bosssoft.itfinance.citycode.engine.web.WebApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中 -->
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!--保留参数原名,否则springmvc参数注解不配置名称时无法正常运行-->
<parameters>true</parameters>
</configuration>
</plugin>
api项目POM
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>17</release>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
<!--保留参数原名,否则springmvc参数注解不配置名称时无法正常运行-->
<parameters>true</parameters>
</configuration>
</plugin>
</plugins>
</build>
6. 配置文件更新
spring.redis.* 改为 spring.data.redis.*
spring:
data:
redis:
jedis:
pool:
max-active: 10
max-idle: 5
max-wait: 10000
min-idle: 5
max-total: 10
升级JDK21
和JDK17类似,修改项目JDK版本后,修改POM文件修改即可打包成功,不需要更新依赖版本。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>21</release>
<source>21</source>
<target>21</target>
<encoding>UTF-8</encoding>
<!--保留参数原名,否则springmvc参数注解不配置名称时无法正常运行-->
<parameters>true</parameters>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.compilerVersion>21</maven.compiler.compilerVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<spring-boot.version>3.2.2</spring-boot.version>
<spring-cloud.version>2023.0.0</spring-cloud.version>
<micrometer-tracing.version>1.0.0</micrometer-tracing.version>
</properties>
压测
机器规格
硬件 | 规格 |
---|---|
CPU | Intel® Core™ i7-9700 |
内存 | 24G |
显卡 | GTX 1650 |
操作系统 | Window 10 |
环境
使用Jmeter压测,条件有限,拨测机器和压测服务部署在同一个节点。挑选了一个业务高频接口来测试,该接口涉及到内存和redis操作,不涉及其他中间件。
打包
对不同JDK版本打出来的包,通过手动指定JDK的方式启动服务,例如:
C:\Java\jdk1.8.0_391\bin\java -jar citycode-engine-service-1.1.7.jar
C:\Java\jdk-17.0.12\bin\java -jar citycode-engine-service-1.1.7.jar
C:\Java\jdk-21.0.2\bin\java -jar citycode-engine-service-1.1.7.jar
开始压测
每个服务每次正式测试前,先100线程预热1分钟
JDK8
100线程,压测1分钟,TPS为2303.5
400线程,压测一分钟,TPS为2123.5
JDK17
100线程,压测1分钟,TPS为2250.8
400线程,压测1分钟,TPS为2246.4
JDK21
100线程,压测1分钟,TPS为2304.6
400线程,压测1分钟,TPS为2214.2
结论
-
关于升级,从JDK8升级JDK17或是JDK21需要对源代码进行改动,并需要升级Spring、Mybatisplus等依赖版本,配置文件也需要调整,还是有一定的工作量。
-
关于压测,我挑选了生产环境高频的业务接口进行测试,得出的结论似乎JDK版本升级对这个服务的性能并没有明显的影响。不过测试条件有限,仅供参考。