“龙井”开箱评测 |Alibaba Dragonwell 新手上路指南


做者|阿里云智能事业群 高级技术专家 陆传胜java

阿里巴巴有着最丰富的 Java 应用场景,覆盖电商,金融,物流等众多领域,是世界上最大的 Java 用户之一。 2019 年 3 月 21 日,阿里巴巴在北京阿里云峰会上正式宣布开源了 Alibaba Dragonwell 8 产品,并创建了 Alibaba Dragonwell 社区来为全球 Java 用户,特别是中文社区的 Java 用户提供长期支持的 JDK 产品。自宣布开源以来,Alibaba Dragonwell 8 受到了国内外 Java 开发者的关注,今天这篇文章就来详解 Alibaba Dragonwell8 的快速安装和使用,同时列出了参与社区建设的几种方式,指望为那些即将安装及使用 Alibaba Dragonwell 8 的开发者提供参考。git

Alibaba Dragonwell 8 介绍

Alibaba Dragonwell 8 是一款免费的 OpenJDK 发行版。它提供长期支持,包括性能加强和安全修复。Alibaba Dragonwell 8 目前支持 X86-64/Linux 平台,在数据中心大规模 Java 应用部署状况下, 能够大幅度提升稳定性、效率以及性能。Alibaba Dragonwell 8 是 OpenJDK 的下游(friendly fork),使用了和 OpenJDK 同样的 licensing。Alibaba Dragonwell 8 与 Java SE 标准兼容,用户可使用 Alibaba Dragonwell 8 开发和运行 Java 应用程序。这次开源的 Alibaba Dragonwell 8 是阿里巴巴内部 OpenJDK 定制版 AJDK 的开源版本, AJDK 为在线电商,金融,物流作告终合业务场景的优化,运行在超大规模的,100,000+ 服务器的阿里巴巴数据中心。github

安装 Alibaba Dragonwell 8

目前 Alibaba Dragonwell 8 只支持 Linux x86-64 平台,而且提供了二进制的预编译 JDK 包,您能够经过下面的简单两步安装 Alibaba Dragonwell 8。web

  • 从 Github 上面 Alibaba Dragonwell 8 项目的下载页面下载预编译的二进制 JDK 包。
    下载页面连接 github.com/alibaba/dra…
  • 将下载下来的 tar 包解压到目标安装目录便可。

安装完毕后,只须要将应用引用 的 JAVA_HOME 指向 Alibaba Dragonwell 8 的安装目录就可使用了。咱们以Tomcat8.5.39 版本为例,为了让 Tomcat 运行在 Alibaba Dragonwell 8上面,只须要在启动Tomcat时使用以下命令:算法

JAVA_HOME=/path/to/dragonwell8/installation  sh tomcat/bin/catalina.sh start
复制代码

为了确认是运行在 Alibaba Dragonwell 8上面,能够进一步经过给 java 命令添加 -showversion 参数来打印 JDK 版本信息加以判断。apache

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-showversion" sh tomcat/bin/catalina.sh start
复制代码

启动完毕后在 tomcat/logs/catalina.out 文件的开头,能够看到 Alibaba Dragonwell 8 的版本信息bootstrap


使用 Alibaba Dragonwell 8 专有特性

在 8.0-preview 这个版本中, Alibaba Dragonwell 8 提供了两个在阿里巴巴的生产环境中进行过普遍验证的特性:JWarmUp 和 Java Flight Recorder。这两个特性都已经在上游 OpenJDK 社区提交了 JEP 或 patch,在上游合并完成以前,咱们但愿让 Alibaba Dragonwell 8 的用户能够提早使用到这两个特性。数组

JWarmUp 快速预热 Java 应用

OpenJDK 使用了 JIT(Just-in-time) 即时编译技术,能够动态的把 Java 字节码编译成高度优化过机器码,提升执行效率,但在编译以前,Java 代码是以相对低效的解释器模式执行的。tomcat

在应用启动完成后、业务流量刚进来的短期内,容易出现的情况是大量 Java 方法开始被 JIT 编译,同时业务请求被较慢的解释器模式执行,最终的结果就是系统负载飙高,可能致使不少用户请求超时。为了解决这个问题,以前的不少作法是使用模拟流量来提早预热应用,JWarmUp 特性提供了一个新的选择,就是利用 Java 虚拟机前一次执行编译得记录来预热本次应用的执行。安全

JWarmUp 的原理以下图所示:


一个典型的应用场景是当应用须要发布新版本的时候,

  • 首先 JWarmUp 在 Beta 环境(或者有着和生产环境相似流量的其余场景)的单台机器上短期执行 Java 应用,并记录、收集这段时间里面 JIT 编译器所作动做的一些元数据。
  • 而后会把这些元数据复制到生产环境的每一台包含了新版本代码的机器/容器里面。
  • 最后在生产环境机器中经过 JWarmUp 参数加载 beta 环境生成的元数据,来指导生产环境的机器在启动应用的过程当中就完成 JIT 预热。

这样当用户请求进入的时候,应用就会处于性能最高的峰值状态。

收集预热数据

还以 Tomcat 应用为例,能够添加下面的命令行参数来在 beta 环境中收集 JIT 编译时生成的元数据,其中参数 -XX:CompilationWarmUpLogfile= 指定的就是生成的 JWarmUp 文件的路径。

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:ReservedCodeCacheSize=512m -XX:CompilationWarmUpLogfile=$PWD/jwarmup.log -XX:+CompilationWarmUpRecording -XX:+CompilationWarmUp -XX:-TieredCompilation -XX:+DeoptimizeBeforeWarmUp -XX:CompilationWarmUpDeoptTime=30 -XX:+PrintCompilationWarmUpDetail" sh bin/catalina.sh start
复制代码

生成以后能够把这个文件经过 OSS、SFTP 等方式传输到生产环境的机器上。

使用记录的数据来预热 Java 应用

在生产环境的机器上,只须要使用下面的参数,就能够利用以前的预热数据来启动一个新的 Tomcat 实例,其中参数 -XX:CompilationWarmUpLogfile= 制定的就是须要被加载的 JWarmUp 文件路径,这个文件应该是上一步收集预热数据时从 beta 环境复制过来的。

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:ReservedCodeCacheSize=512m -XX:CompilationWarmUpLogfile=$PWD/jwarmup.log -XX:+CompilationWarmUp -XX:-TieredCompilation -XX:+DeoptimizeBeforeWarmUp -XX:CompilationWarmUpDeoptTime=30 -XX:+PrintCompilationWarmUpDetail" sh bin/catalina.sh start
复制代码

使用 Java Flight Recorder 分析 Java 应用性能

JFR(Java Flight Recorder)是 JVM 内置的基于事件的性能分析特性,这是 Oracle JDK7u4 版本开始提供的商业特性,2018 年的时候在 JDK11 上开源了这个特性,可是一直没有针对 JDK8 版本的支持。

阿里巴巴和 RedHat、Azul、Amazon 等公司一块儿合做尝试把这个特性移植回 JDK8上,不过该 patch 暂时尚未合并回 OpenJDK8u仓库,咱们在 Alibaba Dragonwell 8 中提供了 Alibaba 移植的 JFR 版本,用于帮助用户提早获取这方面的支持。

JFR 的用法很简单,用户使用命令行参数或者 jcmd 命令控制 HotSpot 输出性能数据到文件中,而后就能使用开源的 jmc 工具在图形界面中打开、分析生成的数据文件了。

使用 JFR 收集性能数据

在 Alibaba Dragonwell 8中,默认状况下 JFR 特性是处于关闭的状态,必须添加命令行参数 -XX:+EnableJFR 来容许使用 JFR 特性。 Alibaba Dragonwell 8 提供了不一样的方式来使用 JFR 采集性能数据。

应用能够能够经过命令行参数指定 JFR 再启动后立马开始采集数据,这个对于诊断启动阶段的问题会颇有帮助。下面的示例命令会在 Java 进程的 JFR 模块初始化后就开始收集 JFR 数据,持续一分钟,而且把数据都输出到名为rec.jfr 的文件中。

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:+EnableJFR -XX:StartFlightRecording=duration=1m,filename=rec.jfr" sh bin/catalina.sh start
复制代码

应用也能够只添加 -XX:+EnableJFR ,而后经过 jcmd 命令在应用启动后的任意时间点开始采集数据,这种状况更加灵活可控,能够知足随时随地进行分析的需求。
以 Tomcat 为例,启动 Tomcat 的命令能够是:

JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:+EnableJFR" sh bin/catalina.sh start
复制代码

当须要收集数据进行分析时,只须要使用目标 Tomcat 进程的 PID 来执行 JFR 对应的 jcmd 命令便可。以 Tomcat 为例,若是须要在指定时刻开始收集 10 秒的数据,那么触发的命令以下:

$ ps ax | grep tomcat
 77522 pts/18   Sl+    0:08 /home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/../j2sdk-image/bin/java -Djava.util.logging.config.file=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XX:+EnableJFR -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/bin/bootstrap.jar:/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/bin/tomcat-juli.jar -Dcatalina.base=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39 -Dcatalina.home=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39 -Djava.io.tmpdir=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/temp org.apache.catalina.startup.Bootstrap start
 98451 pts/22   S+     0:00 grep --color=auto tomcat

$ dragonwell8_home/bin/jcmd 77522 JFR.start duration=10s filename=$PWD/rec3.jfr
77522:
Started recording 3\. The result will be written to:

/home/my/workdir/rec3.jfr
复制代码

10 秒以后能够看到生成了 JFR 数据文件/home/my/workdir/rec3.jfr,使用 JMC 便可进行分析。

也能够不指定收集数据的时间,直接启动 JFR 收集,而且在须要的时候手动把全部生成的数据一次性 dump 到文件,

$ dragonwell8_home/bin/jcmd 2823 JFR.start filename=$PWD/rec4.jfr
2823:
Started recording 4\. No limit specified, using maxsize=250MB as default.

Use JFR.dump name=4 to copy recording data to file.

$ dragonwell8_home/bin/jcmd 2823 JFR.dump name=4 filename=rec4.jfr
2823:
Dumped recording "Recording-4", 332.7 kB written to:

/path/to/my/workdir/rec4.jfr
复制代码

使用 JMC 分析性能

JFR 记录 Java 应用性能数据的输出是一个二进制的文件,咱们借助于 JMC(Java Mission Control) 工具能够在图形化界面里面分析具体的性能数据。这个工具是开源产品,没有包括在 Alibaba Dragonwell 8里面,须要到 OpenJDK 的官方网站下载使用,jdk.java.net/jmc/

请注意, Alibaba Dragonwell8 生成的JFR数据文件须要 7.0 或更高版本的 JMC 工具来分析。

打开 JMC 后,能够点击左侧的详细类别来详细分析采样时间段内发生的各类事件。


诊断调试支持

Alibaba Dragonwell 8 还内置一些方便的诊断特性,主要包括

大对象分配报警

能够经过新的 JVM 参数"-XX:ArrayAllocationWarningSize=",好比下面代码中分配了比较大的数组

public static void main(String[] args) {
    doAlloc(32 * 1024 * 1024 + 1);
}
private static Object doAlloc(int size) {
    return new byte[size];
}
复制代码

执行时若是添加 ArrayAllocationWarningSize 选项就会打印出分配该数组时的 Java 堆栈


详细的 ParNew GC 日志支持

Alibaba Dragonwell 8 默认使用了 CMS (Concurrent Mark Sweep) 算法,新生代使用了 ParNew 算法,因此内置两个针对 ParNew GC 日志的加强

  • 能够经过 jinfo 工具设置 PrintYoungGenHistoAfterParNewGC 选项来在下一次 Young GC 结束的时候打印新生代的对象类型直方图。命令以下
jinfo -flag +PrintYoungGenHistoAfterParNewGC <pid>
复制代码

打印完成后,这个选项会被重置回 false 状态,防止过多的输出,一个典型的输出例子以下:


  • 能够经过-XX:+PrintGCRootsTraceTime 来打印处理每一类 GC 根集所花费的详细 CPU 时间,输出示例以下:

精简版 HeapDump 支持

Alibaba Dragonwell 8 的 jmap 工具支持一个新的 dump 选项“mini”能够在作 heapdump 的时候跳过全部的原始类型数组的内容,从而大大减少生成的 heapdump 文件大小,这对于只须要排查类型、对象关系的场景会比较有帮助。

示例命令以下:



本文做者:jessie筱姜

原文连接

本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索