今年 3 月份,阿里巴巴重磅开源 OpenJDK 长期支持版本 Alibaba Dragonwell 的消息,在很长一段时间内都是开发者的讨论焦点,该项目在 Github 上的 Star 数迅速突破 1400。近日,Dragonwell JDK 8.0.0 正式发布 GA 版本,这意味着其已经具备在生产环境正式运行的能力。
2019 年 3 月,Dragonwell JDK正式开源,发布预览 (Preview) 版本。近日,阿里巴巴重磅宣布 Dragonwell JDK 8.0.0-GA 正式发布,这意味着 Dragonwell JDK 已经完全具备在生产环境运行的能力。在过去三个月时间内,Dragonwell 收到了很多来自社区成员的反馈。那么,本次正式发布的 GA 版本加入了哪些新特性?对开发者而言意味着什么?
龙井 8.0.0-GA 的新变化
8.0.0-GA 的工作目的是为了让 Dragonwell 尽快能够在产品环境里使用。在这个版本里我们同步了 OpenJDK 上游社区 jdk8u212-b04 的最新更新,这也意味着我们同步了上游最新的安全更新和补丁。
除了同步上游,Dragonwell8 还修复了一些在阿里巴巴的 Java 场景下发现的一些非常重要的 Bug,并且经受了阿里巴巴内部场景的检验。同时我们也提供了一个默认的安全证书,这个证书我们会随时更新和维护。
熟悉 Dragonwell 的小伙伴可能都知道,Dragonwell 和 OpenJDK 上游相比提供了一些专有的特性比如:JFR,JWarmUp 等。这些特性在阿里巴巴内部得到了广泛应用,为阿里巴巴的 Java 业务的稳定运行立下了汗马功劳,也可以说是 Dragonwell 的独门武器。在 8.0.0-GA,我们也针对 JFR 特性做了一些修复和兼容性上的改进。所以喜欢 Dragonwell 新特性的的社区小伙伴们可以放心大胆的使用它们了。我们坚信,这些新特性不仅能够阿里巴巴带来价值,同时也能给社区的Java生态带来价值。
8.0.0-GA 的发布具体的内容大家可以参考 github 的 release notes, 戳这里
龙井的新征程
介绍完龙井 8.0.0-GA 的新变化,很多小伙伴已经跃跃欲试了。别忙,在使用之前我们再多唠两句,作为龙井的家人,宝宝该如何成长,我们有着许多的想法,但龙井是社区的孩子,但我们也非常希望社区的小伙伴们能够帮助它们变化成长。所以我们就一起谈谈龙井未来可能发生那些变化。
龙井的自从诞生开始,就吸引了社区的目光,尤其是 Dragonwell JDK 的一些新特性,帮助用户在面临业务挑战时有了更多选择。在今年 ISCA2019 Runtimes in the Cloud Tutorial 中,我们向社区和学术界汇报了 Dragonwell 在新特性上的工作进展,也得到了大家的积极响应。社区的反馈也是我们下一步工作的动力,希望小伙伴多给意见。这个 talk 的介绍在这里 http://www.cs.utah.edu/cloudruntimes/schedule.html#xiaoming ppt 从这里下载 http://www.cs.utah.edu/cloudruntimes/slides/xiaoming.pdf
有兴趣的小伙伴可以看下。
Dragonwell 目前存在的几个特性都是经过阿里巴巴庞大 Java 场景的检验,在稳定性上是非常可靠的。下面我们就来具体谈谈这几个特性。
JWarmUp
JWarmUp 这个特性是为了解决阿里巴巴的双 11 场景中抢购场景 Java 系统 Warmup 的痛点。以普通的 Java 应用举例,JVM 需要经过解释执行 (interpreter) 找到热点,然后通过 JIT 编译器来加速热点方法的运行。对于高并发的场景,应用启动之后会有很长的时间处于寻找热点,编译热点的状态,这时很多性能指标 (CPU 使用率, TPS 吞吐量, RT 响应时间)是不理想的。换句话,当 Java 应用启动并提供服务之后,在相当长的时间内,处于一种 Warmup 的状态,这时候虽然 Java 能够对外提供服务,但服务的质量是比较差的,如果在这个阶段用户的并发比较高,那么就往往会造成服务质量的降级乃至服务崩溃。
为了优化这个过程,通常的工业实践会在 Java 启动后引入"预热" (Warmup) 这个步骤,通过一些人为导入的数据来让应用提前加热,在预热完成之前,用户的请求通过网络控制不让它发送到 Java 进程,在预热完成之后才打开流量限制让 Java 真正提供服务。这个做法可以部分缓解上述问题,但是这个方案在很多场景下会有一些局限性,这是因为很多情况下,获取一份高质量的预热数据是很困难的。而预热数据的正确性直接影响到预热的效果,与实际情况相符的数据可以提高编译的质量,如果不一致,有时反而会造成反面效果,比如一种常见的情况是预热时会漏掉一些重要方法没有被调用。更糟糕的情况是由于和实际情况不一致,导致 JVM “退优化”已编译的方法,重新开始编译,反而恶化了状况。由此可见,如何准备预热数据其实是一个挺复杂的问题,在实际运维中还没有很好的解决方法。
Dragonwell 提出的 JWarmup 技术从 JVM 层面来解决这个痛点,基本原理是利用之前运行的情况找到热点方法和 java class 信息,之后的 JVM 运行实例可以利用上次的信息来预热,不需要通过人为数据来预热。收集热点的实例可以有多种选择,例如在应用集群中选择一个节点,也可以在发布过程中选择一个 beta 发布的阶段来收集。相比之前“人为数据”的方式,主要有这几个优势:
- 收集热点的时候可以利用真实数据,达到更好的编译效果。
- 加速预热的过程。由于热点方法可以在加载后直接编译,节省了解释执行,profiling 等过程。
这个功能在 specjvm2008 的基准测试中,对于某些测试用例,跑分会有明显提高:
# 标准OpenJDK在specjvm2008的xml.validation测试用例上的跑分
Score on xml.validation: 268.07 ops/m
# Dragonwell在specjvm2008的xml.validation测试用例上的跑分
Score on xml.validation: 294.95 ops/m
可以看出 Dragonwell 将 xml.validation 的跑分从 268.07 ops/m 提高到 294.95 ops/m,大概有10%的提高。
这个特性在阿里巴巴的双 11 抢购场景中得到了大量的验证,可以说是 Dragonwell 的秘密武器。目前我们也正在社区努力推进,希望通过 JEP 的方式,把这个功能推进到上游 OpenJDK 社区。毕竟好用的东西,不能只有我们自己有,大家要共同富裕才是王道。目前这个 JEP Draft 正在社区 review 的阶段,小伙伴如果觉得这个特性好用的话,也可以 OpenJDK 社区的邮件列表里代表中国开发者为 Dragonwell 发声。
JFR
JFR 全名是 Java Flight Recorder(Java 飞行记录仪), 是 Dragonwell 的一个功能特性,当该功能被打开后,JVM 能够以非常小的性能开销记录 Java 运行过程中产生的各种运行时数据。产生的 JFR 数据包含 JVM 运行时的各种微观细节,可以被 JMC(Java Mission Control) 进行分析。JMC 是一个桌面应用程序,通过解析 JFR 数据,JMC 能够高效快速的定位线上产品环境的各种故障。它能够分析内存分配热点,方法调用热点,方法调用超时分析,内存泄漏,IO 活动,线程活动等各个方面,帮助 Java 用户保证服务的稳定。
阿里巴巴日常开发过程中遇到的很多问题都是通过 JFR 得到解决的,可以说是 Java 故障诊断的一个利器。JFR 这个功能在 OpenJDK 11 以及以上的版本才有。在阿里巴巴的推动努力下,JFR 功能已经开始被 OpenJDK 社区接受,计划进 OpenJDK 8u 主线,目前社区的移植工作正在 incubator 分支紧张得进行当中,在不远的将来,整个 OpenJDK 8 的下游生态都可以享受这个工作成果。
Dragonwell 作为 JFR 在 OpenJDK 8u 社区工作的参与方,会源源不断的把 JFR 的最新工作成果及时引入 Dragonwell,Dragonwell 的用户可以说有福了。另外,除了 JFR 社区现有的功能,Dragonwell 在 JFR 上也做了很多增强和创新,一方面我们会积极把这些 JFR 的新特性反馈给上游 OpenJDK 社区,另外,在推动上游的同时,Dragonwell 的用户会天然的享有一些特别的福利:在上游社区接受这些特性之前,Dragonwell 会最先开源这些新功能。
神秘嘉宾: ElasticHeap
最后就要介绍下我们的神秘嘉宾 ElasticHeap 了。Dragonwell 会源源不断地把阿里巴巴内部的一些创新特性反馈到社区,ElasticHeap 就是继 JFR,JWarmUp 之后,Dragonwell 带着满满的诚意计划开放的第三个新特性(进入下一个版本发布),OpenJDK 社区也是没有的哦。
大家知道,Java 作为高级语言会带有垃圾回收器,随着程序的运行,Java 会把用户配置的内存逐渐全部使用掉。即使这些 Java 进程后来变得比较空闲,不需要这么多资源了,那这些被占用掉的内存也不会归还给操作系统,从资源利用的角度,这会带来某种意义上的浪费。而 Dragonwell 的 ElasticHeap 就改变了这种情况,这是一个基于 G1 GC 的动态堆弹性伸缩的功能,可以有效节约 java 进程实际物理内存占用。Openjdk8 仅支持在 Full GC 时按照一定规则归还物理内存。而 Dragonwell 的 ElasticHeap 提供了更敏捷有效的归还内存的方式,有如下几个特点:
- 不依赖 Full GC 和其他 STW 暂停处理弹性堆伸缩,不增加额外 STW 开销,不影响 Java 线程服务。
2. 支持多种模式。
a. 根据内存分配速度和 GC 压力自适应调整堆大小(自动归还内存)
b. 根据 jcmd/MXBean 命令主动式限制堆的大小(可整堆限制或分代限制)
下图是阿里巴巴电商应用在双 11 时使用 ElasticHeap GC 压力自适应堆调整的应用的监控图
- 图中上半部分为 CPU 使用率,下半部分为物理内存使用率
- 双 11 整点当服务流量进来时 (traffic peak starts),CPU 使用率大幅提升
- 同时开启 ElasticHeap 堆内存自适应调整时,会配合 GC 压力增大快速回涨堆内存;流量退去 CPU 利用率变小后,GC 压力变小后,迅速的归还物理内存
- 本例中,低流量时归还物理内存约 20-30%
各位小伙伴们请期待吧,ElasticHeap 将在下个版本的发布中揭开神秘面纱。
安装使用
目前 Alibaba Dragonwell 只支持 Linux x86-64 平台,开发者可通过如下步骤使用 Alibaba Dragonwell。
安装 Alibaba Dragonwell
- 选项一:下载预编译 Dragonwell 二进制包
- 从 Alibaba Dragonwell 的 Github 页面下载二进制 tar 包,链接 https://github.com/alibaba/dragonwell8/releases
- 将下载下来的 tar 包解压到目标安装目录即可
- 选项二:使用 YUM 工具安装
Alibaba Cloud Linux 2 YUM 仓库已经正式支持阿里巴巴 Dragonwell JDK,该 YUM 仓库与 Aliyun Linux 17.1, Red Hat Enterprise Linux 7 以及 Centos 7 完全兼容。
对于使用 Alibaba Cloud Linux 2 操作系统的用户,只需要执行 sudo yum install -y java-1.8.0-alibaba-dragonwell
就可以顺利安装。
如果用户没有使用 Alibaba Cloud Linux 2,但使用的 Linux 发行版和 Alibaba Cloud Linux 2 YUM 仓库兼容,那么在 yum install
安装前需要手动将 Alibaba Cloud Linux 2 YUM 仓库添加到操作系统的 YUM 源里去。添加的方法很简单,只需要在 /etc/yum.repos.d/ 里添加一个包含如下内容的 alilinux-plus.repo 文件即可。
# plus packages provided by Aliyun Linux dev team
[plus]
name=AliYun-2.1903 - Plus - mirrors.aliyun.com
baseurl=http://mirrors.aliyun.com/alinux/2.1903/plus/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/alinux/RPM-GPG-KEY-ALIYUN
为 Java 应用启用 Alibaba Dragonwell
对于使用预编译 Dragonwell 二进制包的 JDK 用户,只需将应用脚本或者环境变量中的 JDK 目录变量(一般是 JAVA_HOME) 指向上一步中安装的 Alibaba Dragonwell 目录。然后,重启应用以使用 Alibaba Dragonwell JDK 配置。
如果用户是通过 YUM 工具安装的 Dragonwell JDK,YUM 会在安装过程提示 JDK 的使用方法,提示的内容如下
=======================================================================
Alibaba Dragonwell is installed to:
/opt/alibaba/java-1.8.0-alibaba-dragonwell-8.0.0.212.b04-1.al7
You can set Alibaba Dragonwell as default JDK by exporting the
following ENV VARs:
$ export JAVA_HOME=/opt/alibaba/java-1.8.0-alibaba-dragonwell-8.0.0.212.b04-1.al7
$ export PATH=${JAVA_HOME}/bin:$PATH
=======================================================================
总结
龙井 8.0.0-GA 的发布宣告着 Dragonwell 进入一个新征程,越来越多的新特性将会被开源。也希望社区小伙伴们多多支持,龙井 JDK 将和整个中国的 Java 开发者一起,为增强国内 Java 生态力量而努力,让中国开发者的声音被全世界所倾听。