技术领域
[0001] 本发明涉及一种不需要重起编译部署构件即可以在运行时对构件进行动态演化的轻量级企业构件动态演化的方法。
相关背景技术
[0002] 在现代企业信息化过程中,面向轻量级企业构件(下称“构件”)的编程方法成为主流。 将构件部署在预先定制的应用服务器系统中,就可以用较少的代码实现丰富的企业级应用。 但企业级应用常赋予很强的变化,此时针对这些应用编写的构件就需要更新。
[0003] 构件的更新对于传统应用系统来说是非常复杂的过程,需要经历数个过程:将当前系统的状态缓存,关闭应用系统,更换新的构件,重启应用系统,新的构件提供服务。 这个过程即存在不确定性,又因为要关闭整个系统,所以在更新期间完全无法提供服务。 这对于行业级重型应用是无法忍受的,例如通信系统,银行结算等行业应用,不能通过停止当前系统进行构件的修改和重新部署,因此应用系统必须能够在运行时对构件进行更新。
[0004] 现有的构件更新方法,是通过对构件封装,用系统局部重起的方法来实现对构件进行更新。 这种方法避免了整个应用系统的下线,使得其它业务还能继续提供服务,但对于需要更新的构件,还是存在一段下线的时间,这仍然无法满足应用系统连续运行动态更新的目标。
具体实施方式
[0029] 1、细粒度构件属性的演化
[0030] 在很多应用中,客户会希望在运行时对构件的一些属性进行修改。 此时可以运用细粒度构件属性的演化的达到目的。 一个普通的EJB构件的属性有两种:Java基本类型属性和复杂类型属性。 因此具体的实现方案分两种,对基本类型属性的演化,对复杂类型属性的演化。
[0031] 对基本类型属性的演化
[0032] 在应用服务器中,每个窗口代表一个部署的EJB构件,每个构件包含一个EJB的实例,这个实例就是完成客户功能需求的实例。 当客户的需要发生变化,而且这种变化仅针对基本类型属性时,可以通过反射技术(Reflection)从JVM(Java Virtual Machine)获取构件的属性,然后将其设置为新值。修改模式有两种:对于有状态会话Bean,同一个客户的多次调用使用的是同一个EJB实例,因此一次修改便对所有的后期调用生效。对于无状态会话Bean,客户每次调用时都将生成一个新的EJB实例,因此需要记住的新属性值,然后在每次构件生成时通过反射将其修改。
[0033] 复杂类型属性的演化
[0034] EJB构件中,除了基本类型的属性之外,还包含有复杂类型的属性,如引用其他类型的构件,或者数据源。 容器本身在在实现过程中,对于这些属性通常是使用依赖注入的方式注入目标值,因而当客户需要发生变化时,容器首先检查新的属性和旧属性之间实现相同的接口或者功能是否可以替换。 如果可以替换,在生成新的构件实例时,通过依赖注入,将旧的属性替换为新的属性,即此实现复杂属性的动态演化。
[0035] 2、粗粒度构件替换的演化
[0036] 当客户需要对整个功能构件进行替换时,或当某个功能构件因错误而被强制关闭时系统需要寻找一个功能和其相同或相似的构件来替代。 具体实现方案分两个步骤:构件相似度分析,构件替换
[0037] 构件相似度分析
[0038] 在寻找可替换构件的过程中,有时会寻找到构件接口、属性与方法等与旧构件相同的构件。 有时系统中不存在这样的构件,却存在功能和其相似的构件,此时需要对这些相似的构件进行分析,选出最优的构件进行替换。
[0039] 假设旧构件实现的接口个数为a1,那么可替换的构件必须至少实现这些接口,也可以是它的超集。假候选构件实现的接口数量为a2(大于a1),两个构件的基本相似度可定义为:
[0040] 公式1
[0041] 影响一个构件相似度的还有其注入的属性值,即对其他构件或者是资源的依赖,注入的属性不同,调用时往往产生不同的效果。 注入属性的类型分为注入其他构件和注入资源。 假设旧构件注入的其他构件个数为b1,新构件中注入和旧构件类型相同的属性个数b2,新构件依赖的其他构件的所有个数为b3。那么对其他构件依赖相似度可定义为:
[0042] 公式2
[0043] 假设旧构件注入资源个数为c1,新构件中和旧构件属性相同资源属性个数为c2,新构件所有资源属性个数为c3。 同时对于寻找的一系列构件,在历史过程中发生异常数较少的更适合替换。假设构件的所有调用次数为d1,其中发生的异常次数为d2。对资源依赖相似度和稳定性分别可定义为:
[0044] 公式3
[0045] 公式4
[0046] 两个构件之间的相似度定义为:
[0047] similar=z(a1,a2)*0.6+z(b1,b2,b3)*0.2+z(c1,c2,c3)*0.2-z(d1,d2)*0.1[0048] 公式5
[0049] 在公式1中,当两个构件的实现接口完全一样时,z(a1,a2)结果为1,当新接口的个数远远多于旧接口时,结果为0.9。 在公式2中当注入的其他构件完全相同时,z(b1,b2,b3)结果为1,当没有相同类型时结果为0.公式3和2结果一样。 在公式4中没有异常时结果为0,当调用过程中异常很多时趋近1.因此可知公式5在构件基本相似时,没有异常发生的构件相似度为1.构件在最坏情况下相似度接近0.5。
[0050] 构件替换
[0051] 本发明中,应用服务器采用拦截器及请求转发技术实现构件替换的动态演化。可替换的构件由相似度技术模块得到,构件替换的状态如图1所示,当客户端对构件发出工作请求时,在客户端请求和目标构件之间的截器层会拦截下所有的客户端调用,在通常情况下,所拦截下请求会转发给构件1,即初始设定的构件。 当客户需求发生变化时,系统从相似度计算模块找到最优候选构件-构件2,并用选出的新构件替换掉旧的构件1。 当客户再次发生请求时,拦截器就会将工作将由构件2完成。 在构件替换时,服务器还需要将旧构件的状态迁移到新的构件,满足系统状态的一致性。
[0052] 对本发明做了性能测试。 使用JTone服务器,运行的计算机配置为Inter(R)Core2CPU 2.66GHz,2G内存。测试的页面为输入一个数值,用常量属性演化后输出,使用LoadRunner测试工具模拟500个用户连续5分钟的请问请求。
[0053] 在图2中横轴代表测试时间,纵轴代表系统响应时间。 竖线位置为构件进行属性替换的时间,在1分30秒、3分和4分30秒时进行构件属性替换。 由于反射获取构件属性和修改属性,增加了服务器的负担。 但可以看出,服务器迅速恢复到替换前的平均状况,对客户的影响较小。 本测试证明构件的属性替换是可行的,并代价较小。
[0054] 在图3中横轴代表测试时间,纵轴代表系统响应时间。 竖线位置为粗粒度构件替换的时间,在1分30秒、3分和4分30秒时进行构件替换。 由图知,在构件替换时,由于增加了相似度计算,客户端请求缓冲以及状态迁移,因此增加了服务器响应时间。但可以看到,服务器迅速属性到替换前的平均状况,对客户端的影响较小。 与附图2对比,响应时间最高点是替换前的2部,而构件属性的替换是替换前的1.5倍。而且其必得的时间也更长,这也符合代码编写逻辑,因为属性替换所做的小于构件替换。 本测试证明构件整体替换是可行的,并且代价较小。