写点什么

JRebel 3.0 发布——热插拔重装上阵

  • 2010-05-12
  • 本文字数:2764 字

    阅读完需:约 9 分钟

JRebel 3.0 于不久前发布,我们采访了 Zeroturnaround 的 CTO Jevgeni Kabanov 以详细了解 JRebel 的一些内部工作原理、适用性以及集成问题,并了解 Java 开发者能从这一技术中获得什么益处。

Jevgeni 最近发表的一系列文章,详细讲解了JVM 类加载和运行时类替换的相关内容。本文中的部分内容是从他这一系列文章中提取出来的,另一部分则是我们交流的内容。

开发过程中重新部署或重起Java 应用都引入了不必要的时延,降低了生产效率。 JRebel 旨在通过给 JVM 增加一个处理运行时类替换的特殊javaagent 启动参数来显著缩短开发周期

开发周期与生产效率

为了对生产效率的相关讨论提供支持,Zeroturnaround 收集了来自超过1100 个Java 开发者的统计数据。这些数据是公开的,用来计算平均小时等候时间。在平均小时等候时间中:有6 分钟用来构建的;而大约有10 分半是用来重新部署应用的。

除了直接等待时间外,还有其他隐性时间损耗。在软件开发这样的复杂任务环境中上下文切换也是个问题。有关开发流程的大量信息是保存在短期记忆中的,如果注意力被分散,要想恢复到原来的状态就得花大量的时间。诸如电话、email 及个人需求等工作中断所导致的上下文切换成本在现有文献中已有所讨论。不过前面所说的由基础设施所引起的上下文切换也适用于此。

由于工作期间的成绩更少,低工作效率也会导致开发者积极性降低

有几种方法可以做到在不重新启动应用的情况下更新类,但每种方法都有其问题:

JVM HotSwap

或许有人会说 JVM Hotswapping 可以就地替换字节码,而且已经出现一段时间了(始于 2002 年,JDK 1.4)。但它有严格限制:它只能工作在Debug 模式下,而且只能处理方法体内的变化。它不允许结构的变化或增/ 删类成员。Hotswap 对classloader 也是一无所知,它只是通过类名来识别类,并且只能处理已存在的类。

从Java 5 开始,hotswapping 可通过 instrumentation API 来使用。JRebel 也使用了该 API,但仅仅用于底层类及类加载器,并没有在实际的重加载处理中运用。

JVM 的复杂性(尤其是垃圾回收、内存布局及 Hotspot)使得提供一个通用的透明类字节码替换方案比较困难。

其中一个问题是对象实例的状态必须不受影响,否则相关实例必须全部替换,对他们的所有引用也都要更新(包括级联变化)

应用服务器重部署(Redeployment)/ 热部署(Hotdeployment)

大多数 servlet 容器、应用服务器和 OSGi 的重部署特性实现思路都类似。

用专用类加载器(classloader)加载一个应用服务器(或其部分),如果你删除了对所有已加载类以及 classloader 的引用,你就能彻底卸载该应用并用一个新的 classloader 重新加载它。但是通常情况下,从 JVM 中彻底删除对所有实例、类或 classlodar 的引用是不可能的。

这样的话老应用仍部分存在,只是不再使用罢了。于是类加载器泄漏(classloader leaks)就会被引入,导致在连续重部署后内存消耗增加。

热部署可以有效地重启应用。为了恢复应用的状态,这些状态必须提前被保存并被重新应用或加载到“新”的应用或模块中。

当前基于组件的框架如 Grails 或 RIFE 都自己负责处理组件状态。这就是为什么用新 classloader 重新装载的组件在这些框架中不存在问题的原因。新组件的状态在框架中已经存在。组件的颗粒性也可以让很小的 bundle 被瞬时重新加载。
不过这种方式重新加载类存在一个普遍问题,即类的新老版本可能同时存在,框架必须小心处理这一问题。

JRebel

JRebel 原先叫 JavaRebel,自 2007 就有,它采取了一种不同的方式。当一个类被仪表化的(instrumented)类加载器加载时,在线创建了一个间接产物(indirection),其能够在重新加载时保持所有实例的身份和状态。该间接产物基于“高级编译技术(类似抽象字节码)”,会产生一个主类和几个匿名类、以及一些启用 JIT 的支持类。JRebel 让方法调用尽可能完整,以减少对性能的影响。基于同样的原因,它避免将 JDK 仪表化(instrumenting JDK)。为了给重加载类提供反射 API 支持,该 API 调用的结果也相应地被修改。

创建额外的类会导致多分配 20% 到 40% 的空间。按照 Jevgeni 的说法,较小的类及深层继承都会占用更多的内存。但是这是由内部实现引起的,你不应该依赖于它。

为了在一个打包的部署中重新加载类,JRebel 允许开发者将打包文件结构映射(通过 rebel.xml 配置文件)回开发空间(development workplace),以便让修改过的类以及所有其他资源得以重新加载。

由于 JRebel 对重载 / 刷新资源进行了全面综合考虑,因此也能够更新各种框架和容器的配置及元信息。为了能给不同框架都提供恰当的刷新设施,JRebel 提供了一个开源API 用以开发 JRebel plugins 。现有可用开源 plugin 中包含支持以下框架的 plugin:Guice、Spring、Tapestry 4、Struts 2、Wicked、Stripes、WebObjects。这些都是随发行包一起发行的。

上述三种不同类重加载方法的区别在zeroturnaround 网站上有相应的比较矩阵加以说明。

JRebel 3.0 改进之处

JRebel 3.0 版于 4 月 16 日发布,包含了不少重要改进。

  • 性能提升,启动速度快两倍,内存使用减少 25%-30%
  • 支持添加静态属性和修改 enums(自动初始化)
  • 改进 EJB 支持及 plugins(尤其针对 IBM WebSphere、JBoss、Oracle Weblogic),支持 EJB 接口更新、依赖注入、对 EJB 3 支持更到位
  • JPA —— 提供 OpenJPA 和 Hibernate plugins,能够反应实体、注解和配置变化(beta 版,默认禁用)
  • 全面支持 JSP scriptlet,外部代码变化在 scriptlet 中立即生效
  • 为 JSF 配置和注解变更提供 Mojarra plugin
  • 更多的可用插件,支持:Spring、Guice、Seam、Weld Groovy、Wicket、Google App Engine、AspectJ、Struts 1 和 2
  • 对诸如 Javassist 和 cglib(被许多其他工具所使用)这样的字节码框架提供特殊支持

按照 Jevgeni 的说法,最后一个问题比较棘手。当给类添加方法时,字节码框架的调用句柄接所收到了他们预期之外的合成方法调用。因此我们用一个redefineClass()方法对 JRebel API 进行了扩展,该方法还允许重定义字节码代理。使用该 API,可以重写部分代理实现以允许动态类更新。现在有两个 plugins 专门支持这些框架。

还有一个遗留问题是 JDK 动态代理,由于他们对代理接口的限制因此很少需要集成。

JRebel 的目标是具备更多兼容性,以能够与任何基于 Java 的底层架构无缝集成。其中重要的一步是改进了与 EJB 的集成。

为了获得更好企业集成特性,Zeroturnaround 还针对老技术(Java 1.4、老的应用服务器版本、EJB 1.x/2.x)和集中许可证管理提供了 JRebel Enterprise Add-On 。该附加组件是作为免费更新提供给当前所有用户的。

许可和支持

JRebel 可在个人许可(USD 59)或商业许可(USD 149)下使用。你还可以免费试用30 天并有30 天的退款保证。

Zeroturnaround 对开源社区也提供支持,为开源开发者 Scala 开发者提供了免费许可。

查看英文原文: JRebel 3.0 Release - Hotswap Reloaded

2010-05-12 08:587295
用户头像

发布了 150 篇内容, 共 45.6 次阅读, 收获喜欢 10 次。

关注

评论

发布
暂无评论
发现更多内容

如何快速提升你的技术能力

老张

自我提升 技术 优化体系

GaussDB(分布式)实例故障处理

华为云开发者联盟

数据库 后端 华为云 华为云GaussDB 华为云开发者联盟

自定义Key类型的字典无法序列化的N种解决方案

EquatorCoco

Java 开发语言 key

潮流风潮:Meme预售疯狂背后的原因和趋势分析

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

低代码:软件开发的性价比之王

EquatorCoco

软件开发 低代码 项目开发

探索全球加密市场:市场规模、趋势和参与者解析

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

连接数据,畅通协作!企业数字化管理再升级

聚道云软件连接器

案例分享

最全参赛指南!2024 年(第 17 届)中国大学生计算机设计大赛大数据主题赛现已开赛

ModelWhale

大数据 数据分析 交叉学科 中国大学生计算机设计大赛 乡村发展

探索ORM技术:如何轻松管理数据库并提高操作效率?

测吧(北京)科技有限公司

测试

干货满满丨万字超全 ElasticSearch 监控指南

腾讯云可观测平台

Elastic Search

国际化物联网卡解决方案立项一周年

开源物联卡管理平台-设备管理

物联网 IoT eSIM安全 java 技术提升

零售饮料企业凭借精准铺货策略与动态调整,通过指标平台精准把脉,赢得线下渠道的主动权

Kyligence

什么是设计模式?

不在线第一只蜗牛

数据库 设计模式

Python教程:生成Excel并更改表头

霍格沃兹测试开发学社

人大金仓助力国家电网调度中心培养国产数据库专家人才

科技热闻

Sol代币发行:探究Solana生态系统中Sol代币的发行

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

深度解析:DApp钱包燃烧质押合约挖矿系统的开发

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

打造安全壁垒:JWT鉴权提升应用的访问安全性

测吧(北京)科技有限公司

测试

纯血鸿蒙来了!鸿蒙App开发需如何提速

Geek_2305a8

首次代币发行(ICO)的成功:概念化、理论和系统分析

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

守护你的在线业务!如何选择合适的服务器高防公司?

一只扑棱蛾子

高防服务器 高防服务器公司

Chrome不支持正则搜索?那我们自己写一个

JYeontu

前端 chrome扩展 浏览器插件 Chrome插件 Chrome Extension

鸿蒙Next升级有便捷的方法?

Geek_2305a8

软件测试学习笔记丨Pytest常用的异常处理方法

测试人

软件测试

Docker Kill/Pause/Unpause命令详细使用指南

霍格沃兹测试开发学社

鸿蒙5.0发布时间已定!移动开发加速器何处寻?

Geek_2305a8

C++中虚表是什么

快乐非自愿限量之名

c++ 算法 开发语言

成为Flask专家:利用蓝图实现功能模块化管理的关键路径

测吧(北京)科技有限公司

测试

如何快速运用iPaas与协议进行接口对接

RestCloud

ipaas 接口对接 协议对接

JRebel 3.0发布——热插拔重装上阵_Java_Michael Hunger_InfoQ精选文章