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

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

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+ 服务器的阿里巴巴数据中心。

安装 Alibaba Dragonwell 8

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

安装完毕后,只需要将应用引用 的 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 版本信息加以判断。

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

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

使用 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 代码是以相对低效的解释器模式执行的。

在应用启动完成后、业务流量刚进来的短时间内,容易出现的状况是大量 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 的官方网站下载使用,https://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筱姜

原文链接

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

“龙井”开箱评测 |Alibaba Dragonwell 新手上路指南的更多相关文章

  1. 活字格企业 Web 应用生成器新手上路指南

    活字格是一款企业 Web 应用生成器,使用了类 Excel 的设计界面,通过简单的拖拽操作,就能快速制作出一个 Web 信息管理系统.在整个使用过程中无需专业软件知识,没有任何技术门槛,能轻松实现各行 ...

  2. 重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell

    原文地址:https://yq.aliyun.com/articles/694603 本文作者:阿里开源  本文来自云栖社区合作伙伴"阿里系统软件技术",了解相关信息可以关注&qu ...

  3. 重磅发布:阿里开源 Open JDK 长期支持版本 Alibaba Dragonwell

    3 月 21 日北京阿里云峰会,阿里巴巴正式宣布对外开源 OpenJDK 长期支持版本 Alibaba Dragonwell.作为 Java 全球管理组织 Java Community Process ...

  4. Flume NG Getting Started(Flume NG 新手入门指南)

    Flume NG Getting Started(Flume NG 新手入门指南)翻译 新手入门 Flume NG是什么? 有什么改变? 获得Flume NG 从源码构建 配置 flume-ng全局选 ...

  5. OpenGL教程之新手上路

    Jeff Molofee(NeHe)的OpenGL教程- 新手上路 译者的话:NeHe的教程一共同拥有30多课,内容翔实,而且不断更新 .国内的站点实在应该向他们学习.令人吃惊的是,NeHe提供的例程 ...

  6. 转-spring-boot 注解配置mybatis+druid(新手上路)-http://blog.csdn.net/sinat_36203615/article/details/53759935

    spring-boot 注解配置mybatis+druid(新手上路) 转载 2016年12月20日 10:17:17 标签: sprinb-boot / mybatis / druid 10475 ...

  7. 千呼万唤始出来——uFUN开发板2.0开箱评测

    前言 今年3月,我参与了面包板社区组织的第一批uFUN开发板评测活动,并有幸能获得试用机会,那是我第一次了解到uFUN这个项目及背后的故事,4月份,uFUN 2.0版本来了,收到了张工送的一块样板,后 ...

  8. 东芝半导体最新ARM开发板——TT_M3HQ开箱评测

    前言 最近从面包板社区申请到一块东芝最新ARM Cortex-M3内核的开发板--TT_M3HQ,其实开发板收到好几天了,这几天一直在构思怎么来写这第一篇评测文章,看大家在社区也都发了第一篇评测,我也 ...

  9. (转)2019年 React 新手学习指南 – 从 React 学习线路图说开去

    原文:https://www.html.cn/archives/10111 注:本文根据 React 开发者学习线路图(2018) 结构编写了很多新手如何学习 React 的建议.2019 年有标题党 ...

随机推荐

  1. Leetcode94. Binary Tree Inorder Traversal二叉树的中序遍历(两种算法)

    给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 递归: class So ...

  2. 微信小程序之组件的集合(二)

    继续微信小程序开发的学习,继续跟着老师的讲课思路来学习,继续开发项目中所用到的组件 一.导航栏navi组件的开发 1.新建组件的文件结构 这个就是先新建目录navi.然后在navi文件夹中新建comp ...

  3. 用JetBrains PyCharm 2017.2创建运行Django程序

    在JetBrains PyCharm 2017.2里选择 文件(F) 新项目 点击  三角形  运行 修改Urls.py """S14Djngo URL Configur ...

  4. Vue.js系列之项目搭建(vue2.0 + vue-cli + webpack )

    1.安装node node.js环境(npm包管理器) cnpm npm的淘宝镜像 从node.js官网下载并安装node,安装过程很简单,一路“下一步”就可以了(傻瓜式安装).安装完成之后,打开命令 ...

  5. 理解es6箭头函数

    箭头函数知识点很少,但是要理解清楚,不然看代码会很不适应的. 1. 最简单的写法 x => x*x 可以理解为 我的x要被转化为x*x,所以实际相当于下边的这个 function (x){ re ...

  6. ThinkPHP中实现微信支付(jsapi支付)流程

    https://blog.csdn.net/sinat_35861727/article/details/72783988 之前写过一篇文章讲了 PHP实现微信支付(jsapi支付)流程 ,详见文章: ...

  7. SOFARPC学习(一)

    接触SOFARPC,是从一个好朋友(女程序媛)的推荐开始,目的是从头到尾了解这个框架,包括使用方法和源码解析. 当学习一个新东西的事物,我总喜欢先总体把握,在深入细节,这样就可以有种高屋建瓴的感觉,否 ...

  8. applyMiddleware源码中的闭包

    闭包都是个老掉牙的话题了,这次又提起,是因为重看Redux源码时发现了applyMiddleware里的用法很巧妙.我们先看一个简单的例子. var a = (num) => num + 1 v ...

  9. mysql查询 包含某个字符的记录

    从excel导入数据库的时候,发现poi自动把电话号码转换为科学计数法了 所以要把带e的筛选出来 SELECT * FROM t_customer WHERE phone like '%E%'; 然后 ...

  10. Linux远程管理Windows程序Rdesktop详解

    #rpm –q rdesktop                       //查找是否已经安装 #yum install rdesktop                //使用yum安装 rde ...