AI实践哪家强?来 AICon, 解锁技术前沿,探寻产业新机! 了解详情
写点什么

从本地原生到云原生,Alibaba Dragonwell 静态编译的实践与挑战

  • 2019-10-25
  • 本文字数:3083 字

    阅读完需:约 10 分钟

从本地原生到云原生,Alibaba Dragonwell静态编译的实践与挑战

近些年来,云原生(Cloud Native)的概念席卷业界,其核心元素之一就是如何提高云上业务的响应速度。随着应用微服务化、容器化程度的不断提高,应用的执行响应速度也在不断提升,逐渐触及到了Java程序速度提升的天花板——Java 自身的启动运行开销。


虽然 Java 从最初的单独解释执行演进到 JIT(实时编译)和 AOT(提前编译)后,在运行时 peak performance 和冷启动性能方面都取得了大幅进步,但如虚拟机启动、代码解释执行、JNI 调用、反射开销、静态初始化检查开销等 Java 虚拟机和运行时本身的耗时点始终存在,并且耗时占比随着应用程序运行时间的降低而愈加突出。要进一步提高云原生应用的启动执行速度,突破 Java 自身的启动运行开销性能瓶颈,就必须在传统的 Java 程序编译启动执行过程之外,另辟蹊径。

Java 静态编译简介

Java 静态编译技术是一种激进的 AOT 技术,通过单独的编译阶段将 Java 程序编译为本地代码,在运行时无需传统 Java 虚拟机和运行时环境,只需操作系统类库支持即可。目前较成熟、受到业界广泛关注的开源 Java 静态编译器是由 Oracle 开发的GraalVM SubstrateVM(以下简称 SVM),图 1 展示了目前基于 SVM 的阿里巴巴静态编译项目的基本编译过程。


SVM 遵循封闭性假设(closed-world assumption, 即运行时所需的所有内容必须在编译时提供),将应用程序代码及其所依赖的三方 jar 文件和Alibaba Dragonwell代码编译为本地机器码,同时也将用 Java 编写的 Runtime 编译为机器码,两者被编到一个 elf 可执行文件或 so 共享库文件中,实现代码的自举。运行阶段只需直接执行 elf 文件,或者在其他 C/C++程序中调用 so 文件中发布的 API 即可。



图 1:SVM 静态编译基本过程


可以认为静态编译技术实现了 Java 语言与原生 Native 程序的“合体”,将原本的 Java 程序编译成为了一个自举的具有 Java 行为的原生 Native 程序,由此兼有 Java 程序和原生 Native 程序的优点。

Alibaba Dragonwell 静态编译实践

极速启动:Meta 节点应用 Serverless 化

从 Java 程序角度看,经过静态编译后 Java 程序具有更快的启动速度、更低的内存占用、更小的发布体积,在云上部署时从服务拉起到响应用户的请求所需的时间更短,非常适合云原生的需求。


以蚂蚁开源中间件项目 sofastack 的服务注册中心Meta节点应用为例,该项目验证了静态编译在 Serverless 应用上的可行性。图 2 展示了以传统 Java 方式运行和静态编译程序运行的几项数据的比较。



图 2:Sofastack 注册中心 Meta 节点静态编译前后性能对比图


左上图的服务启动时间指服务完全启动到可以接受用户请求的状态所需的时间;右上图的可执行文件大小指包含了运行 Java 程序所需的所有依赖资源的 fat jar 包和静态编译出的 elf 可执行文件的大小比较,虚线框代表没有显式打入 fat jar 的 Alibaba Dragonwell;底图的运行时内存消耗则是以相同压力请求测试时,两个版本应用各自的内存使用情况。从图中可见静态编译的代码在这些指标上较传统 Java 程序有质的提升,服务启动时间降低了 17 倍,可执行文件大小降低了 3.4 倍,运行时内存降低了一半。

多语言支持:RocketMQ 客户端应用

从 Native 原生代码角度看,在静态编译的帮助下开发人员可以用 Java 编写出 Native 代码,较以往的 C/C++开发效率更高、为同一业务维护多个语言版本的成本更低。


在这方面的探索中,阿里巴巴发布了静态编译版本的 RocketMQ 客户端,为 RocketMQ 进一步 Serverless 化提供了语言无关的运行时保障,实现了一套内核的多语言支撑。图 3 展示了 RocketMQ 客户端的多语言维护的示意。



图 3:RocketMQ 客户端多语言实现示意图


在引入静态编译技术之前,同一需求需要用两种语言分别实现不同的 SDK,最终运行在不同的环境中,开发和维护成本高。在静态编译的支持下,同一需求只用 Java 单一语言开发,然后沿图中绿色路径静态编译得到 Native Code。当然此外还需要一部分适配工作,将拟暴露的 API 用 SVM 定义的 C-Java 转化协议包装起来。


与先前单独编写 C++客户端相比,静态编译方案给多语言客户端的快速开发和后续管理带来了诸多优势:


  • 基于 Java 统一内核实现,避免功能重复开发;

  • 面向接口设计开发,内核实现插件化加载;

  • 功能升级只需分发内核,用户无感知;

  • 客户端实现闭包,运行时无任何第三方依赖。


目前静态编译版本的 RocketMQ 客户端已稳定可靠地服务阿里巴巴集团内部以及阿里云超过 10+ 业务场景,包括网络延迟在内的客户端启动时间相比 Java 原生客户端提升 30%,达到与 C++版应用同等的启动性能。

静态编译的挑战和 Alibaba Dragonwell 的应对

然而世界上没有银弹,静态编译技术也不例外。兼有 Java 和原生 Native 代码两者的优势是以牺牲部分 Java 动态特性为代价换取来的,表格 1 列出了在 SVM 中受限制的 Java 特性。封闭性假设要求在编译时必须获取运行时所需的全部信息,这与 Java 的动态性相矛盾,是静态编译对传统 Java 限制最大的部分。代码 Native 化是指由于丢弃了 Bytecode,传统上基于 Bytecode 的特性便不再被支持。缺少工具指缺少调试静态编译后代码的工具,如 Heap Dump、Thread Dump、代码调试等功能在 SVM 社区版中都没有提供。


原因分类存在限制的特性具体解释
封闭性反射、动态类加载、动态代理、JNI反射、序列化反序列化、MethodHandler编译时需要完全掌握运行时的信息
代码native化插桩、JVMTI、agent编译为本地代码后已不存在bytecode
缺少工具Heap dump,Thread dump、调试部分存在于企业版中,社区版为提供


表格 1:SVM Java 特性限制一览


可以看到 SVM 静态编译仅支持了传统 Java 特性的子集,而且对生产级的应用还缺少良好的工具支持。阿里巴巴正在结合自己的业务场景与 SVM 开源社区紧密合作,以 Alibaba Dragonwell 和 SVM 为基础,积极探索如何缩小静态编译和传统 Java 之间的鸿沟。


一方面逐步扩展静态编译能够支持的特性子集,使静态编译能够适用于更多的业务场景。比如针对 JDK 原生序列化反序列化的需求,通过预执行输出动态加载的类,将其加入静态编译的代码范围中,并自动生成需要的反射配置信息提供给编译器,最终实现对序列化反序列化特性的支持。另一方面探索适合面向静态编译的 Java 编程模型,帮助开发人员便捷地开发出适合静态编译的 Java 程序。


阿里巴巴对 Alibaba Dragonwell 进行静态化剪裁,一边定义了使用反射、动态类加载等不完全支持特性时的规则,并通过 javac 做强制检查。一边将静态编译完全不能支持的特性从 Alibaba Dragonwell 中去除,帮助开发人员以静态编译的思维开发新的 Java 程序。最后增加了对 Thread dump,Heap dump 支持,并开发了针对阿里巴巴业务场景的更有效的 GC 算法。这些对业务场景的不断实验和打磨,在成熟后也会贡献反哺到社区。

总结

静态编译技术是一种兼具传统 Java 程序和本地原生代码程序二者优点的技术。以静态编译的原生代码助力云原生应用,既保持了传统 Java 的开发流程和效率,又消除了 Java 自身固有的性能瓶颈,显著改善服务拉起响应请求的速度,阿里巴巴也通过自身实践,证明了静态编译技术在实际生产中的可行性。


在长期的 Java 开发实践中,阿里巴巴对 OpenJDK 不断优化总结开发出了其下游 Alibaba Dragonwell JDK,现已运行在 100,000+服务器上,为阿里巴巴的各项业务提供基础服务。相信随着 Alibaba Dragonwell 静态编译版本进一步成熟,将能够支持更多原生代码应用部署上云。


作者介绍:


林子熠,阿里巴巴集团 JVM 团队技术专家。上海交通大学软件工程专业工学博士,毕业后加入华为编译器与编程语言实验室参与方舟编译器的研发工作,现于阿里巴巴 JVM 团队主要负责 Java 静态编译技术在 Java 服务端的开发与应用。


2019-10-25 14:435934

评论 2 条评论

发布
用户头像
看起来牛逼,性能提升上来,直接Java能干很多活了
2019-11-06 16:03
回复
后续应该缺少架构方面的内容了吧,基本上不能反射。更多应该关注到业务层了,简化了架构部分
2020-01-04 16:34
回复
没有更多了
发现更多内容

TiDB 和 Java 的简单 CRUD 应用程序

TiDB 社区干货传送门

HarmonyOS Connect FAQ第四期

HarmonyOS开发者

HarmonyOS

利用现有数据库管理系统创建一个安全的分布式数据库集群

亚马逊云科技 (Amazon Web Services)

大数据 分布式 Tech 专栏

采访22年第一批秋招上岸的同学后,我整理了这份Java面试手册

Java面试那些事儿

Java 编程 程序员 架构 面试

如何在 TiDB Cloud 上使用 Databricks 进行数据分析 | TiDB Cloud 使用指南

TiDB 社区干货传送门

离线部署系列文章之一:TiDBv5.3.0集群部署&源码部署 Haproxy v2.5.0

TiDB 社区干货传送门

实践案例 版本升级 管理与运维 安装 & 部署 扩/缩容

PingCAP Clinic 服务:贯穿云上云下的 TiDB 集群诊断服务

TiDB 社区干货传送门

云堡垒机主要针对运维过程中的什么进行管理和审计?

行云管家

运维 堡垒机 IT运维 云堡垒机

某站下载量过W的近4000页“Java面试合集”号称大厂面试零门槛

收到请回复

Java 程序员 面试 金九银十

如何让 TiDB 集群管理“更省心”?TiUniManager(原 TiEM)使用教程来了

TiDB 社区干货传送门

膜拜阿里!首次发布「10亿级并发系统设计文档」(内部绝密)

退休的汤姆

阿里 面经 Java工程师 秋招 并发系统设计

私有化部署的低代码平台 更安全的信息化解决方案

力软低代码开发平台

离线部署系列文章之二:TiDB集群升级(5.3.0->5.4.2)&缩扩容 TiDB Server、PD、TiKV、TiFlash

TiDB 社区干货传送门

版本升级 集群管理 管理与运维 安装 & 部署

传统堡垒机数据可以迁移到云堡垒机上吗?方式有哪些?

行云管家

云计算 网络安全 堡垒机

五天玩转EMAS Serverless

云端explorer

云计算 Serverless emas

什么!阿里最新版Spring Cloud Alibaba项目文档,竟将重要组件弃用

收到请回复

Java spring 阿里巴巴 面试 spring-cloud

手把手教你实现 TiFlash 向量化函数丨十分钟成为 TiFlash Contributor

TiDB 社区干货传送门

TiFlash Proxy 模块介绍

TiDB 社区干货传送门

大数据训练营毕业总结

Geek_Q

TiDB 和 Golang 的简单 CRUD 应用程序

TiDB 社区干货传送门

魅族高校新生充电计划进行中,直播课让科目一新生直呼厚道

极客天地

2022 OceanBase 年度发布会:发布四大策略,迈入4.0时代

OceanBase 数据库

希捷亮相OCP China Day 2022,与生态伙伴共话绿色存储之道

极客天地

一对一直播软件——如何实现音视频传播?

开源直播系统源码

软件开发 直播系统源码 一对一语音聊天软件 语音直播系统

基础到高级涵盖11个技术,Alibaba最新出品711页Java面试神册真香

收到请回复

Java 大数据 架构 编程语言 语言 & 开发

对话ACE第五期:到底什么才是真正的HTAP?

OceanBase 数据库

Go-Excelize API源码阅读(十四)——GetSheetFormatPr

Regan Yue

开源 源码刨析 Go 语言 8月日更 8月月更

20万字的《Kafka运维实战宝典》PDF现在免费下载了

石臻臻的杂货铺

大数据 kafka

故障处理 | DM 搭建 MySQL 8.0 同步链路报错:code=26005

TiDB 社区干货传送门

安装 & 部署 TiDB 源码解读

多并发下线程创建、释放的阻塞问题

TiDB 社区干货传送门

从本地原生到云原生,Alibaba Dragonwell静态编译的实践与挑战_服务革新_林子熠_InfoQ精选文章