SpringBoot3新特性
AOT和JIT
JIT学java虚拟机的时候因该知道 just in time,就是Java 实时编译器,将字节码转换成机器指令。这个是java跨平台的基础。
AOT就是Ahead of time,预编译或者提前编译。如果使用了预编译,很明显没法再实时编译,就没法跨平台了,所以java之前一直都没有AOT。(直接和操作系统打交道,没有JVM了)
AOT的优点
- 启动和运行的速度快
- 打包体积很小
这些优点,在云原生,快速扩展部署应用,有用处
AOT缺点
- 编译后的程序无法跨平台(需要特定平台的编译器编译)
- 不支持动态功能,例如AOP。(因为没有JVM了,也没没法实时编译,就没法在运行时改了)
JIT在高并发场景下的问题
在热点服务一启动后,往往会出现服务超时,然后过一段时间服务又正常恢复的情况。
JVM在执行指令的过程中,有两种方式,一种是正常的,在运行时解释每一条字节码为机器码,然后交给硬件运行。另一种是为了提高效率,当jVM发现一个class文件访问频率很高,那么就很触发JIT,将class文件编译成机器码,然后以后就直接使用机器码,而不用一遍一遍的解释这个class文件中的内容了。
JIT实时编译会需要一定的时间,只有类的访问频率到达阈值才会触发。
问题分析
高并发服务一启动,大量的类被转类JIT实时编译,这样占用了CPU的性能,这些请求创建的线程就卡在队列中,等到程序设置的超时达到之后就会自动返回超时响应。
解决方案
- 预热,主动将热点类激发到JIT阈值,等待JIT编译完毕即可开放服务
- 流量控制,启动时小流量,这样JIT不会同时编译大量的类,运行几分钟再放到正常流量。(逐步放大)
GraaIVM实现AOT打包
和HotSpot同样的是Java虚拟机,GraaIVM是oracle公司出品的虚拟机,这个虚拟机比传统的HotSpot强大,不仅支持传统的基于JVM规范的语法Java,scala,kotlin,还支持c,c++等基于LLVM的语言,还支持Javascript,python,Rust,Ruby,R等语言。
这个虚拟机可以帮助Java实现AOT功能。
SpringBoot3使用的JDK17,所以需要GraalVM的版本22.3.0
下载安装
下载好后,配置环境变量
然后需要安装native-image
在线安装可以通过命令 gu install native-image (gu是之前下载的graaivm中的bin的工具,所以需要先下载好上面的GraaIVM并配置好环境变量才能使用)
离线下载,因为在线下载实际上会从github上下载,在国内这个比较慢,可以手动在如下地址进行下载
下载好文件之后,使用gu install -L 文件所在地址,来将native-image安装到graaivm中。
安装成功之后可以通过gu list命令查看安装好的组件。
创建SpringBoot3项目
版本兼容问题,这个版本的GraaIvm只能使用Sprintboot3 3.0.0版本,3.0.1都会不兼容
如果在创建的时候没有这个选项,可以在项目创建好后手动修改配置文件来实现更改版本号
项目需要添加依赖:
支持本地打包
下载Visual studio 2022
目的是为了使用C++桌面程序的命令行打包工具打包AOT文件成exe
这两个选项需要勾选
具体操作
进入打包目标项目所在目录,使用visual studio中的命令行工具x64 Native Tools Command Prompt for VS 2022
指令命令 mvn -Pnative native:complie
这一点在SpringBoot3的官方文档中也有提到。