一种基于Agentmain的生产环境在线类替换方法与流程

文档序号:17089398发布日期:2019-03-13 23:16阅读:943来源:国知局
一种基于Agentmain的生产环境在线类替换方法与流程

本发明涉及java应用工程领域,特别是一种基于agentmain的生产环境在线类替换方法。



背景技术:

在java应用工程领域,如何在不停机、低用户感知,甚至用户无感知的情况下进行类的热替换从而升级系统或者修复系统bug一直是难以解决的问题,特别是在生产环境上进行类的替换更是如此。

java虚拟机对于类加载采用双亲加载机制,已经加载过一次的类,无论后续如何修改类都无法对线上系统生效,若要生效只能重启虚拟机,但对于一个运行的线上生产系统来说,重启意味着暂停服务,用户检验极差,极易造成重大损失。

在java应用工程中,类的加载采用双亲委派机制。当应用中需要使用类时,由当前类加载器接收加载类的请求,首先将加载任务委托给其父类加载器,如果该父类加载器还有祖先类加载器,依次递推加载,如果祖先加载器可以完成类加载任务,就返回加载的类对象,否则由当前加载器自己去加载。此种类加载过程可以避免对一个类的重复加载,但也导致了一个类一旦被加载就无法改变的问题。

针对上述问题现有技术方案通常采用自定义的类加载器的技术来解决。自定义类加载器监听需要改变的类或者由系统主动触发,在编译文件发生改变的时候,重新加载该类,并且需要改变创建对象的行为。在使用可能改变的类时候,必需使用自定义的类加载器来重新加载类的编译文件。在应用的设计阶段就要并行设计需要更新的类,在业务代码中进行分类,哪些是可能改变的类,哪些是不变的类,并且一旦做出决定在后续开发中就要遵守这个规则不能改变,否则就需要返工代码。由此可以看出,该解决方案需要额外的工作量,缺乏灵活性,并且类的每次修改都需要重新生成加载器存在内存泄露的风险。

从上述描述的解决过程可以看出自定义类加载器技术存在以下不足,首先,同一个类加载器还是无法加载两个相同类名的类,对于每次修改都需要新增加载器来加载类,对于更新升级频繁的应用存在内存泄漏的风险;其次,在应用的设计开发阶段不仅要进行业务方案的设计开发,更要并行的进行更新类方案的设计开发,这极大增加工作量,并且更新代码与业务代码紧密耦合、侵入性大,缺乏灵活性;最后,对于已经运行未进行更新设计的老旧系统无法运用,难以推广。



技术实现要素:

有鉴于此,本发明的目的是提出一种基于agentmain的生产环境在线类替换方法,可以在不重启系统的前提下,让系统能感知到java编译文件的变化,更改类的行为,从而达到升级系统或者修复系统bug的目的。

本发明采用以下方案实现:一种基于agentmain的生产环境在线类替换方法,包括以下步骤:

步骤s1:在java环境中创建agentmain更新机制,所述agentmain更新机制包括agent组件以及关联组件,其中agent组件包括agentmain拦截以及classfiletransformer;

步骤s2:所述agent组件在应用程序入口main方法之前,通过方法切面拦截的方式添加agentmain方法,所述agentmain方法能够在类加载前修改类的编译文件字节码。

进一步地,所述classfiletransformer的接口根据实现情况自定义实现方式以满足不同的类加载方式,不需要重新定义类加载器,不会产生内存垃圾而造成内存泄露。

进一步地,所述agentmain更新机制是独立于业务系统应用程序来运行的,与真正的业务代码完全解耦,通过所述关联组件将agent组件插入到应用程序与虚拟机之间来拦截应用程序的类加载行为。

进一步地,所述关联组件包括attacher以及java虚拟机b。

进一步地,对于已经存在的线上系统,单独部署一套agentmain更新方案来更新老旧系统的类行为。

与现有技术相比,本发明有以下有益效果:

1、本发明的agentmain更新机制不需要重新定义类加载器,不会产生内存垃圾而造成内存泄露。

2、本发明的agentmain更新机制是独立于业务系统应用程序来运行的,与真正的业务代码完全解耦,可根据实现业务需求灵活配置。

3、本发明的agentmain更新方案可以更新老旧系统的类行为,具有很好的通用性,具备一次开发到处适配的特性。

附图说明

图1为本发明实施例的原理框图。

具体实施方式

下面结合附图及实施例对本发明做进一步说明。

应该指出,以下详细说明都是示例性的,旨在对本申请提供进一步的说明。除非另有指明,本文使用的所有技术和科学术语具有与本申请所属技术领域的普通技术人员通常理解的相同含义。

需要注意的是,这里所使用的术语仅是为了描述具体实施方式,而非意图限制根据本申请的示例性实施方式。如在这里所使用的,除非上下文另外明确指出,否则单数形式也意图包括复数形式,此外,还应当理解的是,当在本说明书中使用术语“包含”和/或“包括”时,其指明存在特征、步骤、操作、器件、组件和/或它们的组合。

如图1所示,本实施例提供了一种基于agentmain的生产环境在线类替换方法,包括以下步骤:

步骤s1:在java环境中创建agentmain更新机制,所述agentmain更新机制包括agent组件以及关联组件,其中agent组件包括agentmain拦截以及classfiletransformer;

步骤s2:所述agent组件在应用程序入口main方法之前,通过方法切面拦截的方式添加agentmain方法,所述agentmain方法能够在类加载前修改类的编译文件字节码。

在本实施例中,所述classfiletransformer的接口根据实现情况自定义实现方式以满足不同的类加载方式,不需要重新定义类加载器,不会产生内存垃圾而造成内存泄露。

在本实施例中,所述agentmain更新机制是独立于业务系统应用程序来运行的,与真正的业务代码完全解耦,通过所述关联组件将agent组件插入到应用程序与虚拟机之间来拦截应用程序的类加载行为。

在本实施例中,所述关联组件包括attacher以及java虚拟机b。

在本实施例中,对于已经存在的线上系统,单独部署一套agentmain更新方案来更新老旧系统的类行为。

具体的,本实施例的具体实现步骤如下:

步骤1、定义一个manifest.mf文件,文件中必须包含agent-class。

例如:

manifest-version:1.0

can-redefine-classes:true

agent-class:com.linewell.agent.agentmaintraceagent

can-retransform-classes:true

步骤2、创建agent-class指定的agentmaintraceagent类,该类必须包含agentmain方法;创建真正实现类编译文件替换的实现类simpleclassfiletransformer。

例如:

在agentmain中调用了instrumentation实例,执行了inst.retransformclasses(business.class)来转换目标类,也就是business类。注意,instrumentation中还有一个类似的方法redefineclasses,这个方法是在类第一次加载时使用,如果要在类加载后生效则需要使用retransformclasses方法。simpleclassfiletransformer简单的实现了classfiletransformer接口的transform方法,该方法返回了新的业务类business的class字节数组。classfiletransformer的生效周期与虚拟机相同,在类加载器加载编译文件的时候都会进行拦截。

步骤3、将manifest.mf和agent类打成jar包。

例如:javaagent.jar

步骤4、将javaagent.jar包载入应用系统虚拟机。

例如:

本实施例基于agentmain的在线类替换方案的架构如图1所示。agent组件在应用程序入口main方法之前,通过方法切面拦截的方式添加agentmain方法,此方法可以在类加载前修改类的编译文件字节码。无论是首次加载,还是每次更新完类进行旧类的替换,都会经过classfiletransformer的transform方法,也就是说,真正重新加载类的逻辑可以在transform这个方法中实现,本实施例方案正是利用这个特性来达到更新类的目的。在agentmain更新机制中,agent组件中的classfiletransformer接口需要根据实现情况自定义实现方式以满足不同的类加载方式,不需要重新定义类加载器,不会产生内存垃圾而造成内存泄露。agentmain更新机制是独立于业务系统应用程序来运行的,与真正的业务代码完全解耦,通过关联组件将agent组件插入到应用程序与虚拟机之间来拦截应用程序的类加载行为。对于已经存在的线上系统,可以单独部署一套agentmain更新方案来更新老旧系统的类行为,并且此方案具有很好的通用性,方便移植,通过简单配置就能够推广到其它系统。

本实施例采用java虚拟机底层技术agentmain实现,与业务无耦合,跟业务方案无关,在上线后可以根据实际需要来更新替换类,具有很高的灵活性,并且不需要重新定义类加载器,不存在内存泄露风险。由于不需要在业务开发阶段就进行设计,而是采用了虚拟机的底层技术,因此也可以很好的运用于老旧系统,具有很好的推广性。

以上所述仅为本发明的较佳实施例,凡依本发明申请专利范围所做的均等变化与修饰,皆应属本发明的涵盖范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1