-
Notifications
You must be signed in to change notification settings - Fork 498
QuickStart框架使用指南
目前QuickStart框架已经支持Alibaba Dragonwell Extended Edition 8.16.17-GA (以及之后的版本)。
使用 -Xquickstart
参数 run 两次应用,第二次 run 时,根据第一次 run 时的数据,应用可以得到启动性能提升。
下表中的特性都可以通过QuickStart框架使用。
描述 | 约束 | |
---|---|---|
AppCDS | AppCDS全称为Application Class Data Sharing。第一次使用时,虚拟机把用户使用的 classes dump 到文件中去。后续的进程则可以直接使用该文件加速类加载流程,从而达到启动加速的效果。 | 1、不支持自定义class loader |
EagerAppCDS | AppCDS 的激进版本,阿里 JVM 团队研发,效果会较大程度上优于 AppCDS。 | 用户需要自行保证class与加速文件一致性,即class变化,每次发布时cache都需要重新生成。 |
应用进程需要至少 run 两次,来达到最优的启动效果。
该 java 进程的角色 | 描述 | |
---|---|---|
第一次启动应用 | Tracer |
- 默认在此进程退出时 dump 出共享的缓存文件 - 或者,用户也可以手动使用 jcmd <pid> QuickStart.dump 命令在进程启动完成后的任意时间 dump 出共享的缓存文件。 |
第二次及更多次启动应用 | Replayer |
- 第二次或更多次 run 应用时,应用的 java 进程是一个 Replayer 角色- 读取 Tracer 进程 dump 出来的用于启动加速的共享缓存文件进而执行优化,获得性能收益 |
通过增加-Xquickstart
参数体验QuickStart的加速启动效果。
# Trace阶段: 第一次运行生成dump文件,用于后续加速启动(也可以直接运行java类而非jar包)
<Alibaba-Dragonwell8>/bin/java -Xquickstart:verbose -jar <jar-name>
# Replay阶段: 此后(第二次以及之后)运行使用dump文件,达成快速启动
<Alibaba-Dragonwell8>/bin/java -Xquickstart:verbose -jar <jar-name>
使用QuickStart框架的java参数的格式是:-Xquickstart[:option,...],用户可以通过-Xquickstart:help
查看细节说明
设置当前QuickStart的运行模式
作用 | 示例/额外说明 | |
---|---|---|
help | 打印 QuickStart 使用说明和帮助。 |
-Xquickstart:help |
destroy | 删除 QuickStart 指定的共享目录,不保证正在使用共享文件的 java 进程不受影响。删除后会直接退出进程。 | -Xquickstart:destory |
printStat | 打印当前缓存内容 | -Xquickstart:printStat |
profile | 只记录profile信息不触发dump。这意味着本次运行仅收集程序运行的类的基本信息并保存到cache中。(只是第一次运行程序的一部分,需要和dump结合使用,才能完整生成加速文件。) |
-Xquickstart:profile |
dump | 根据cache目录中的profile进行dump。这意味着本次运行利用之前profile产生的cache中的文件生成加速文件(是第一次运行程序的另一部分,此前必须运行过profile) |
-Xquickstart:dump |
(空白) | 如果不加任何mode,虚拟机会自动帮助用户判断是第几次运行——如果没有缓存,则这一次会进行trace(profile+dump),如果已经有缓存,则这一次会直接replay。 | -Xquickstart |
verbose | 打印 QuickStart 框架的输出日志。 | -Xquickstart:verbose |
设置额外信息
作用 | 示例/额外说明 | |
---|---|---|
verbose | 打印 QuickStart 框架的输出日志。 | -Xquickstart:verbose |
path= | 规定快速启动的缓存位置,如果没有,则使用默认路径/<your-home-dir>/alibaba.quickstart.sharedcache/ 用户可以使用 -Xquickstart:path=xxx 或 export QUICKSTART_CACHE_PATH=xxx 来指定 path 的地址为 xxx
|
按 1 2 3 的优先级处理:1. -Xquickstart:path=<path> 或者指定环境变量2. QUICKSTART_CACHE_PATH=<path> 3. 如果 1 2 都没指定,默认目录是用户目录 ~/alibaba.quickstart.sharedcache/ ,没有会自动创建。 |
containerImageEnv= | 执行获取容器镜像的环境变量,这里的环境变量应该是容器的唯一ID。 | -Xquickstart:containerImageEnv=<env> |
设置定制化的启动加速需要
作用 | 示例/额外说明 | |
---|---|---|
appcds | 用 +/- 开启/关闭 appcds 和 eagerappcds 特性 |
-Xquickstart:verbose,+appcds |
eagerappcds | 用 +/- 开启/关闭 eagerappcds 特性- 关闭后,默认使用官方App CDS特性 |
-Xquickstart:verbose,+eagerappcds |
EagerAppCDS支持自定义Classloader。
EagerAppCDS本身配置了一些常用的ClassLoader,但是如果用户自定义ClassLoader,则需要通过配置告诉JVM如何唯一来标识这个ClassLoader,你可以基于JVM自带的ClassLoader进行修改,修改以后通过参数:
-Dcom.alibaba.util.xmlconfig=/path/to/classloader-config.xml
。配置文件会基于最新的配置文件进行增量的修改。
原有的配置文件:https://github.com/dragonwell-project/serverless-adapter/blob/main/src/main/resources/classloader-config.xml
- 除了进程退时时触发dump以外,还可以通过jcmd供用户手动dump:
- 使用
jcmd <pid> QuickStart.dump
命令来非交互式做 dump,只会生效一次。(如果不使用 jcmd,那么默认会在用户进程退出时做dump)
- 进程可以通过读取环境变量来获取QuickStart是否生效以及当前运行的角色
- 在进程内读取
ALIBABA_QUICKSTART_ROLE
这个环境变量:- a. 如果没检索到此变量,说明 quickstart 没生效
- b. 如果检查到
TRACER
/REPLAYER
/NORMAL
这些字符串,都说明 quickstart 生效了。其中- I.
TRACER
说明 quickstart 在 trace 的步骤中; - II.
REPLAYER
说明 quickstart 在 replay 的过程中; - III. 如果是
NORMAL
说明当前在 quickstart 的一个特殊中间流程中,可以不用特殊处理。
- I.
在8.17.18版本后额外增加路径替换功能:用户需要设置-Dcom.alibaba.cds.cp.reloc.envs
表示需要替换的环境变量,这个变量替换会作用于cds中的trace阶段中记录的classpath路径,e.g.
- Trace阶段:用户设置了
-Dcom.alibaba.cds.cp.reloc.envs=ABC,DEF; export ABC="ABC"; export DEF="DEF";
,在第一次运行时,cds记录了classpath是ABC/xxx.jar;DEF/yyy.jar - Replay阶段:当用户使用CDS再次运行程序时,如果
export ABC="abc"; export DEF="def"
,则在校验时,CDS会自动寻找abc/xxx.jar和def/yyy.jar来进行验证
报错名称 | 错误描述 | 原因 | 解决 |
---|---|---|---|
Fail to create LOCK file | Trace/Profile阶段:正常运行但不做Trace或者Profile | 前一个进程或者多个进程同时在一个目录中进行Trace或者Profile | 如果其它进程Trace或者Dump失败了,可以通过-Xquickstar:destory删除掉;如果是多个进程,确保path参数不冲突 |
Error: non-empty directory '%s' | Dump阶段:Dump失败 | AppCDS默认不支持dump class文件夹中的class,默认不支持原因是由于class无法快速校验是否发生变化。 | 如果应用自己能确保class与jsa的一致性,可以通过选项-XX:+IgnoreAppCDSDirCheck开启 |
metadata file may be destroyed by another process | replay阶段:继续运行但不加速 | cache目录中缺少文件metadata。 cache可能不是一个合法的目录或者metadata被误删除了 |
重新Trace确保cache目录中的文件完整 |
VM Version isn't the same | replay阶段:继续运行但不加速 | Trace阶段的JDK与Replay的JDK版本不一致,由于版本不一致,可能Java Archive文件在二进制上不兼容会有crash风险 | 确保Trace和Replay的JDK版本一致性 |
An error has occurred while processing the shared archive file. | replay阶段:终止进程 | Trace和Replay时classpath中的jar包文件的修改时间或者大小不一致。 | 确保文件的修改时间和大小与Trace时完全一致。 |
A jar file is not the one used while building the shared archive file | replay阶段:终止进程 | Trace和Replay时classpath中的jar包文件的修改时间或者大小不一致。 | 确保文件的修改时间和大小与Trace时完全一致。 |
Required classpath entry does not exist | replay阶段:终止进程 | Trace和Replay时的classpath发生变化。 | 确保classpath完全一致。 |
CDS加速的是Class加载的性能,如果启动过程中加载的类数量不多,那么可能效果不明显。
如果要确认启动过程中类的数量,可以通过增加选项-verbose:class
或者jcmd <PID> PerfCounter.print
查看。
只有符合一定条件的类才能被加速,如下是常见的原因导致无法加速:
原因 | 如何确认 | 如何规避? |
---|---|---|
类校验失败 | 检查生成cache的目录下logs/jsa.log搜索关键词Preload Warning: | 这些类可能是一些比较老的JDK编译的类,可以考虑更新到比较新的版本 |
JavaAgent对类做了redefine或者transform | javaagent可以通过命令行参数或者动态的attach。 命令行参数检查是否有-javaagent 动态attach可以检查一下是否运行有其它java进程 |
无法规避。由于transform实际上修改了Class,会导致Class以及相关的子类都会失效,可能会影响大量的类无法加速。 可以通过尽量减少不必要的transform来缓解 |
jar的文件大小或者时间发生了变化 | 检查日志中quickstart是否有相关的warning或者error | 要确保jar大小以及修改时间与dump时的一致性 |
业务应用的 ClassLoader 没有被注册在 EagerAppCDS 的配置文件中(我们已经生成了规则自动注册了包括 tomcat 的WebappClassLoader 、springboot 的 LaunchedURLClassLoader 等等。但是业务应用完全可以自定义自己的 classloaders。这样这些不在白名单的 loaders 不会被 EagerAppCDS 识别。 |
业务应用自身熟悉自己定义的 classloader 的话,可以识别出来;以及如果非以上原因的情况下加速效果不好的话,可以考虑这点。 | 1. 可以通过com.alibaba.util.Utils.registerClassLoader(ClassLoader loader, String name) 这个 API 给自定义的某个 classloader 对象(注意是对象级别) 注册一个独一无二的自定义名称,这样 EagerAppCDS 就可以识别这个我们自定义的 classloader。2. 写一个 xml 的配置文件来让EagerAppCDS 自动识别。这种方法可以避免侵入业务代码。 |
Alibaba Dragonwell