AIGC 应用、数据分析等企业 10+ 热门专题课,就在极客时间企业版>>> 了解详情
写点什么

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

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

    阅读完需:约 10 分钟

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

AI 大模型超全落地场景&金融应用实践,8 月 16 - 19 日 FCon x AICon 大会联诀来袭、干货翻倍!

近些年来,云原生(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:435458

评论 2 条评论

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

如何做好FAQ页面的设计

小炮

FAQ

【刷题第六天】35. 搜索插入位置

白日梦

5月月更

设计微博系统中”微博评论“的高性能高可用计算架构

流火

面试答不上Java并发编程?阿里P8提供的27道并发面试解析,请查收

Java浪潮

Java spring 架构 编程语言

Gartner发布CIO最新调研结果,可组装EBC备受瞩目

金蝶云·苍穹

企评家,专注企业评价,为企事业单位提供信息数据支撑

企评家

强强联合,天翼云安全能力再升级!

天翼云开发者社区

云计算 基础设施 云服务 云安全

Maven 简介及安装

Emperor_LawD

maven 5月月更

百度智能云特色城市业务指挥平台,助力城市管理更智能

百度开发者中心

模块五

ASCE

下个牛市,Web3世界的龙头项目PlatoFarm能否踏足山巅

BlockChain先知

关于数据保护官DPO(34/100)

hackstoic

企业安全 DPO 数据保护官

Hoo网格策略活动仍在进行中 震荡市场持续狂欢

区块链前沿News

量化策略 Hoo 网格

全国唯一!这家企业的工业互联网平台上云啦!

天翼云开发者社区

云计算 解决方案 云服务 工业互联网 云平台

为什么你的maven打包老是出现问题

ZuccRoger

5月月更

微博评论高性能高可用计算架构设计

踩着太阳看日出

架构训练营

linux之yum源设置代理

入门小站

Linux

面试还不会Spring?阿里P8总结的100道面试解析,让你实锤面试官

Java浪潮

Java 编程 架构

企评家|海信视像科技股份有限公司成长性报告简述

企评家

【C语言】指针One之[概念、前言、内存、地址与指针、变量与地址]

謓泽

C语言 5月月更

工业金属零部件质检解决方案详解,让AI质检一步到位!

百度开发者中心

druid 源码阅读(三)初始化连接池(2)

爱晒太阳的大白

5月月更

在线TSV转XML/JSON工具

入门小站

工具

通用池化框架commons-pool2实践

FunTester

ElasticSearch查询流程详解

IT巅峰技术

守护数据安全,天翼云是认真的!

天翼云开发者社区

云计算 云服务 数据安全

架构实战营作业五

库尔斯

#架构实战营

时序数据库在智慧用电领域的应用

CnosDB

IoT 时序数据库 开源社区 CnosDB infra

再谈JavaScript 中的对象解构

devpoint

JavaScript ES6 5月月更 赋值解构 对象操作

在线Base64编码加密解密还原工具

入门小站

工具

基于 Agora SDK 实现 Windows 端的多人视频互动(基于3.6.2版本)

声网

音视频 sdk

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