算算时间,接触OSGi已有2年半时间了,我一直在探索OSGi给我们带来的变化,同时我们也在实施OSGi。回想起来,我对OSGi也算是一见钟情。在接触OSGi的这2年半时间里,我翻译了OSGi规范,并设计了面向.NET的OSGi.NET规范,然后我们用了1年半的时间来实现OSGi.NET产品。之后,我们便开始体验OSGi到底给我们带来了什么。
从2005年开始,我一直在探索一种自组合的插件化框架,从而来构建一个UIShell平台。“UIShell”是我们的梦想,我们希望构建一个SaaS应用商店,从而改变人们开发、购买、使用、销售软件的方式。这个梦想现在已经初步实现了,我们已经构建了第一个融合开发商、消费者和运营商的SaaS应用商店平台。这个平台的构建完全是基于OSGi思想之上的。它实现了这样的一个功能:开发者通过SDK可以开发基于AppStoreSDK的应用,AppStoreSDK是基于OSGi.NET来构建的;消费者通过SaaS应用商店平台来购买SaaS应用,然后下载或者在线使用应用,所有的应用都是运行在AppStoreRuntime之上的,AppStoreRuntime是应用的虚拟运行时,基于OSGi.NET来构建。下图是这个平台的软件体系结构。接下来我来介绍一下我们在OSGi.NET体验。
1 什么是OSGi
简而言之,OSGi是一个动态模块化框架的规范,提供了插件化、面向服务和插件扩展三大功能。这个规范体现非常重要的2点:“模块化”和“动态”。
(1)模块化
在OSGi规范中的模块是一种规范化的完全物理隔离的模块。每一个模块拥有独立的文件结构、独立的类型空间、独立的资源等,模块是重用的单元,不可再切割。模块间互不干扰和影响。
(2)动态
OSGi的动态体现在“面向服务架构支持”、“可扩展”和“生命周期”之上。
在OSGi中,模块是一个完全物理隔离的单元,模块间的通讯是基于面向服务架构思想来实现的。在这里,服务=接口 + 实现。此外,OSGi提供了一个服务注册表,模块可以向服务注册表注册其提供的服务,并且可以从服务注册表动态的查询和绑定服务。由于服务是动态可替换的,我们无法确认我们需要的服务由谁来提供、什么时候提供、什么时候被替换成另一个服务实现。
OSGi构建的模块是完全可重用的模块,如果我们要更新模块的功能,我们有一种选择,那就是使用其提供的模块扩展功能。OSGi的模块扩展是基于ExtensionPoint-Extension方式来实现扩展,提供扩展功能的模块定义一个ExtensionPoint,而实现扩展的模块则定义一个Extension。当实现扩展的模块被启动或停止时,它会向提供扩展的模块注册扩展或者卸载扩展。
每一个模块具有一个确定的生命周期状态,OSGi中有四个持久状态和两个瞬时状态。持久状态分别为Installed、Resolved、Active和Uninstalled,瞬时状态分别为Starting和Stopping。内核暴露了生命周期状态操作接口,从而,我们可以通过更改模块的生命周期状态来改变其提供的功能。
此外,OSGi体现了一种更为灵活的软件体系结构,我把它归纳为“横向切割 + 纵向分层”。在下图中,一个应用系统由Movies模块和Logs功能组成,每一个功能都需要获取用户输入、验证、业务操作和数据访问。在这,应用系统=Movies功能 + Logs功能 + 其它功能,即应用系统是功能的横向组成;然而,功能 = 获取用户输入代码 + 验证代码 + …,即每一个功能是代码的纵向组织而成的。一个应用系统中,功能间的交互一般很少,而功能内部的实现则非常的耦合。OSGi更是体现了这种行为,基于OSGi,每一个应用系统按照功能被横向切割成不同模块,而每一个模块又根据不同的复杂度进行纵向分层架构,这种思想与软件工程的“高内聚、低耦合”非常的吻合。因此,我非常喜欢OSGi提倡的软件体系结构。
目前,OSGi已经被以下公司应用在不同的软件系统。
ØIBM的Eclipse、WebSphere
ØOracle的Weblogic
ØParamus的Infiniflow Service Fabric
ØProSyst的ModuleFusion
ØRed Hat的JBoss
ØSpringSource的SpringSource应用平台
ØSun Microsystem的GlassFish企业服务器
ØBWM车载系统
Ø尤埃SaaS引擎云计算PaaS平台
2 OSGi解决了什么问题
在我看来,OSGi着重解决了以下三个问题:重用性、软件复杂度和可维护性。
(1)可重用性
重用已经是个老话题了,然而重用实施并没有那么简单,原因有:没有统一标准、需要合理的设计与科学的方法、习惯于代码级的低层次重用等。在OSGi里面,重用的粒度为模块。每一个物理隔离的模块为重用的基本单元,其重用的方法可以为:(1)在一个OSGi内核中安装一个模块从而来重用该模块的功能;(2)建立一个模块仓库,实现仓库级重用;(3)直接将一个模块拷贝过来。标准的重用方式,不需要修改任何的代码,不对其它模块产生任何的影响。
(2)软件复杂度
一个复杂的软件系统一般都需要一个架构完整的团队来实施,这样的系统也更需要一个灵活的软件体系架构。我经常听到用户给我的抱怨说,他们的应用系统构建和维护都非常的痛苦。目前RUP、MOF的提出都是要从一定程度上解决软件复杂度问题。我曾在Sybase工作,我们公司也构建了一个框架来保证复杂系统的构建。一个复杂软件系统通常需要几个部分配合来实施。没有一个灵活、符合团队配合的架构,想要实施这种应用系统,其复杂度是可以想象的。OSGi提供了一个模块化组合的思想,由架构师团队对整个系统进行模块化拆分,每一个模块再由不同的团队来实施,这样能够确保团队间不会太多的影响与干扰,也同时降低了模块实施的复杂度。
(3)可维护性
软件维护是一件非常痛苦的事情,通常在修改一个Bug或者添加一个新的功能时,我们都可能会引入新的Bug,这是因为软件内部的依赖比较复杂,从而“牵一发,动全身”。在维护过程中,我们最担心的就是引入Regression,Regression就是“回退”,即我们修改Bug时让以前可以工作的功能不能够再工作了。OSGi通过模块化分割、面向服务通讯方式来降低模块间的依赖与影响,也使得模块维护负担减轻,从而能够改善我们维护的负担。另外,软件升级也是一个问题,没有一个良好的模块化组织,我们并不能通过局部更新来更少的影响整个软件系统。
我们在维护的过程中,也常碰到另一个问题,就是经常需要到客户所在地进行维护。OSGi能够支持动态部署,我们可以远程的动态增加与禁止某项功能、更新某个模块,甚至建立一个统一更新的模块仓库,这样我们不再需要到客户那里实施更新,减少我们的成本。
附件是我上个周末实施的一次关于OSGi.NET的培训和示例,大家可以看一下,以后多多交流。
/Files/baihmpgy/体验OSGi.NET.pdf
/Files/baihmpgy/MovieStore.zip
要运行示例,你需要下载UIOSP安装包,尤埃开放服务平台试用版下载