今年3月份,Dragonwell JDK 正式开源 ,发布预览(Preview)版本。近日,阿里巴巴重磅宣布 Dragonwell JDK 8.0.0-GA 正式版发布,这意味着 Dragonwell JDK 已经完全具备在生产环境运行的能力。
在过去三个月时间内,Dragonwell 收到了很多来自社区成员的反馈。那么,本次正式发布的 GA 版本加入了哪些新特性?对开发者而言意味着什么?
在很大程度上,Java 由 Oracle 长期主导。自 2017 年底,Oracle 就开始陆续转变 Java 策略,逐渐将 Oracle JDK 中的商业功能开源给社区,并宣布不再提供免费商业版本更新,不提供安全更新和漏洞修复支持。
这对开发者而言意味着什么?如果你是 Oracle JDK 8 的用户,原 License 尚可免费使用,但之后若希望得到持续安全更新则需要为此付费。如今,在 Oracle 主导下的 Java 大环境已经发生变化。作为最大的 Java 的用户之一,阿里巴巴几乎拥有世界最大规模的 Java 应用集群,肯定需要为此采取一些行动。
基于此,阿里巴巴决定开源 OpenJDK 长期支持版本 Alibaba Dragonwell ,一是因为其自身拥有大量 Java 客户和业务需求,阿里巴巴希望他们可以继续免费享受到 JDK 的所有功能;二是考虑到不少开发者可能会做出新的选择,阿里巴巴决定开源该项目,为开发者提供一个新的参考。
在过去三个月时间内,阿里巴巴方面对该项目进行了持续维护和更新。据了解,本次 GA 版本的主要目的是让 Dragonwell JDK 尽快在生产环境中可用。该版本同步了 OpenJDK 上游社区 jdk8u212-b04 的最新更新,并通过了阿里巴巴内部生产环境测试。该项目最初开源时,阿里云智能基础产品事业部资深技术专家李三红在接受 InfoQ 独家专访时反复强调一个观点:
Alibaba Dragonwell 一定是 OpenJDK 的下游,每个 Alibaba Dragonwell 发行版都会同步上游最新更新,并经过阿里巴巴内部大规模的应用集群测试。同时,阿里巴巴也会积极将 AJDK 上的技术积累贡献到 OpenJDK,积极参与社区的项目更新和维护。
除了同步上游社区,Dragonwell 8.0.0 还修复了一些在阿里巴巴场景下发现的重要 Bug。同时,该版本提供了默认安全证书,并会随时更新维护。
此外,关注 Dragonwell JDK 的开发者应该知道,Dragonwell 与 OpenJDK 上游相比提供了一些专有特性,比如 JFR,JwarmUp 等。作为全球最大的 Java 用户之一,阿里巴巴内部拥有数量非常庞大的 Java 开发人员和服务器,这也是其业务发展使然。上述新加入的特性在阿里巴巴内部得到了广泛应用,为阿里巴巴 Java 业务的稳定运行立下了汗马功劳,也可以说是 Dragonwell JDK 的独门武器。在本次的 GA 版本中,阿里巴巴也针对 JFR 特性做了一些 BUG 修复和兼容性上的改进,具体详情可以访问 Github 上的 Release Notes 。
Alibaba Dragonwell 是一款免费的 OpenJDK 发行版,其提供长期支持,包括性能增强和安全修复,主要针对的场景是数据中心大规模 Java 应用部署情况下,Java 应用稳定性、效率以及性能的优化与提高。从目前公开的功能和披露的规划上来看,Dragonwell 8 具有下述三大重要特性:
JwarmUp 是为了解决双十一抢购场景下,阿里巴巴 Java 系统 warmup 的痛点。以普通的 Java 应用举例,JVM 需要经过解释执行 (interpreter) 找到热点,然后通过 JIT 编译器来加速热点方法的运行。对于高并发场景,应用启动之后会有很长时间处于寻找热点、编译热点的状态。这时,很多性能指标 (CPU 使用率、TPS 吞吐量、 RT 响应时间) 不是非常理想。换句话说,当 Java 应用启动并提供服务之后,在相当长的时间内处于 warmup 状态。这时,虽然 Java 能够对外提供服务,但服务质量较差,如果该阶段的用户并发较高,那么就会造成服务质量降级乃至服务崩溃。
为了优化这一过程,通常的工业实践会在 Java 启动后引入 ” 预热 “(warmup) 步骤,通过人为导入数据来让应用提前加热。在预热完成之前,用户请求通过网络控制不让它发送到 Java 进程,在预热完成之后才打开流量限制让 Java 真正提供服务。这个做法可以部分缓解上述问题,但是该方案在很多场景下会有一些局限性,在很多情况下,获取一份高质量的预热数据是很困难的。而预热数据的正确性直接影响预热效果,与实际情况相符的数据可以提高编译质量,如果不一致,有时反而会造成反面效果,比如一种常见的情况是预热时漏掉重要方法调用。更糟糕的情况是由于和实际情况不一致,导致 JVM“退优化”已编译的方法,重新开始编译,反而恶化了状况。由此可见,如何准备预热数据其实是一个挺复杂的问题,在实际运维中还没有很好的解决方法。
Dragonwell 提出的 JWarmUp 技术从 JVM 层面解决这一痛点,基本原理是利用之前运行的情况找到热点方法和 java class 信息。之后,JVM 运行实例利用上次的信息来预热,不需要通过人为数据预热。收集热点的实例可以有多种选择,例如在应用集群中选择一个节点,也可以在发布过程中选择一个 beta 发布阶段来收集。相比之前“人为数据”的方式,主要有如下优势:
该功能在 specjvm 的基准测试中对于某些测试用例,启动阶段跑分会有 10% 的提高。该特性在阿里巴巴的双 11 抢购场景中得到了大量验证。目前,阿里巴巴正在社区努力推进,希望通过 JEP 的方式将该功能推到上游 OpenJDK 社区。
下图是阿里一个应用在“双十一”期间使用 JWarmUp 时的效果:
说明:图中蓝线是正常启动 (默认开启分层编译),红线是启用 JWarmUp 的 CPU 使用率。
(1)是开启了 JWarmUp 选项,在应用启动时候,流量进来之前积极加载和编译方法。
(2)是流量进来的时刻。
(3)是正常模式启动下,CPU 消耗 100% 维持了 70s。(注:作图省略了一部分数据)
(4)对应的绿线是稳定后 CPU 的使用率。
可以看到应用 JWarmUp 后在流量进来的时候 JWarmUp 可以减少大量 CPU 消耗,更快的进入全速运行状态。
JFR 全名是 Java Flight Recorder(Java 飞行记录仪)。众所周知,JFR 是 Oracle JDK 的商业收费功能,需要付费才可使用,虽然后期通过 OpenJDK 11 开源,但 Java 8 的用户群体无法使用且该部分人群较为庞大。因此,阿里巴巴开源 Dragonwell JDK 之时,便决定将该功能移植到 Alibaba Dragonwell 8 中供开发者使用。Java 开发人员可以通过 JFR 收集 JVM 运行过程中的详细 profiling 信息,配合 Java Mission Control (JMC), 提高 Java 应用的问题诊断及性能优化效率。
在本次的 GA 版本中,当 JFR 功能被打开,JVM 能以非常小的性能开销记录 Java 运行过程中产生的各种运行时数据。产生的 JFR 数据包含 JVM 运行时的各种微观细节,可以被 JMC(Java Mission Control) 进行分析。JMC 是一个桌面应用程序,通过解析 JFR 数据,JMC 能够高效快速定位线上产品环境的各种故障,分析内存分配热点,方法调用热点,方法调用超时分析,内存泄漏,IO 活动,线程活动等,帮助 Java 用户保证服务稳定。
据了解,阿里巴巴日常开发过程中遇到的很多问题都是通过 JFR 得到解决的,可以说是 Java 故障诊断利器。如上所言,JFR 功能在 OpenJDK 11 以及以上版本才有,但是在阿里巴巴的推动努力下,JFR 功能已经被 OpenJDK 8u 社区接受,确定会被移植进 OpenJDK 8u 主线,目前社区的移植工作正在 incubator 分支紧张进行当中。在不远的将来,整个 OpenJDK 8 的下游生态都可以享受这一功能特性。
除社区现有功能外,Dragonwell 在 JFR 上做了很多增强和创新。作为 JFR 在 OpenJDK 8u 社区的参与者,阿里巴巴表示会将 Dragonwell 在 JFR 方面的最新工作成果及时引入社区。在上游社区接受这些特性之前,Dragonwell 的开发者将会最先使用这些新特性。
据阿里巴巴内部披露,ElasticHeap 特性将很快在下一个版本开源。作为高级编程语言,Java 带有垃圾回收器。随着程序运行,Java 会把用户配置的内存逐渐消耗掉。即使这些 Java 进程后来变得比较空闲,被占用掉的内存也不会归还操作系统,从资源利用角度,这会带来某种意义上的浪费。阿里巴巴方面表示,ElasticHeap 主要用于改变这一情况。
据介绍,ElasticHeap 是一个基于 G1 GC 的动态堆弹性伸缩功能,可以有效节约 Java 进程实际物理内存占用。Dragonwell JDK 的 ElasticHeap 提供更敏捷有效的归还内存方式,主要有如下特点:
下图是阿里巴巴电商应用在双 11 时使用 ElasticHeap GC 压力自适应堆调整的应用的监控图:
1. 图中上半部分为 CPU 使用率,下半部分为物理内存使用率
2. 双 11 整点当服务流量进来时(traffic peak starts),CPU 使用率大幅提升
3. 同时开启 ElasticHeap 堆内存自适应调整时,会配合 GC 压力增大快速回涨堆内存;流量退去 CPU 利用率变小后,GC 压力变小后,迅速的归还物理内存
4. 本例中,低流量时归还物理内存约 20-30%