说到 OSGi,首先要讲模块化的软件开发思想。随着科技和需求的发展变化,现在的软件正在变的越来越庞大,伴随而来的是软件的复杂度呈指数级增长,使得现代软件无论是在开发还是维护上都变的越来越困难。为了摆脱这样的困境,软件架构师们化整为零,将庞大的软件集合划分为一个个易于开发和维护的模块。模块的出现,从根本上解决了上面的问题。模块的优势体现在:
- 使资源能够合理分配:将软件模块化后,就可以分配独立的团队去处理独立的模块,从而将资源合理分配。这样既便于管理,又会降低整个软件的设计的复杂性。因为每个独立的团队可以专心去设计和实现其模块,而不用通盘考虑整个软件的复杂性。
- 增加软件重用性:每一个模块都是一个独立功能的封装,可以被轻松的用到其他的软件开发过程中,节省了资源和成本。
- 易于开发和维护:软件分成一个个模块,每一个模块都被独立的开发和维护,当软件出现问题后,就能很容易的定位到出问题的模块,降低了软件的复杂度和维护成本。
在 JAVA 领域,OSGi 是其实现模块化最重要的方法。OSGi 是一门非常成熟的技术,因为它已经存在 10 多年了,OSGi 联盟负责管理并制定相关的规范。该联盟在 2009 年 9 月发布了最新版的 OSGi Service Platform V4.2 规范,在企业专家组的大力推动下,新的 Service Compendium V4.2 规范中引入了 Blueprint Services, Remote Services, Bundle Tracker 等用以支持企业级应用的新标准,从而为 OSGi Service Platform 进军企业级市场奠定了基础。
OSGi 为企业级应用程序开发带来了极大的便利和好处,IBM WebSphere 秉承这一优势,作为 OSGi 技术的主要推动力量,也在其最新的 WAS 版本 8.0 中,提供了全面的企业级 OSGi 支持,允许您使用 OSGi 改进自己的应用程序和服务。
如果您正在使用 WebSphere Application Server V7.0,也可以通过 OSGi application Feature Pack 这一免费的功能部件包,体验 OSGi 应用的开发和管理。
模块化的标准有三点:一是要保证每个模块在逻辑和功能方面都是完整独立的来增加模块的可重用性;二是要求每个模块都应该定义良好的外部接口和依赖项以便与其他模块松散耦合;三是模块应该将内部包和外部模块有效的隔离,来避免内部包的更新对外部模块的影响。普通的 jar 包只能满足模块性的第一个标准。OSGi 将应用程序划分成不同组件(称为 Bundle),把 Bundle 作为模块化单元,每个 Bundle 实际上就是一个 jar 包,jar 包中除了类和资源信息以外,还包括 OSGi 模块层运行需要的 OSGi 元数据。元数据中定义了该模块依赖于哪些外部模块中的包、以及该模块提供了哪些包可供外部模块引用,从而满足了模块化的另外两个标准。
OSGi 通过两种方式提供了良好的可见性控制,首先,每个模块只能看见它预先声明的依赖包,其次每个模块可以预先声明其内部哪些包可被其他模块使用,而其他包则是私有的。即使是最简单的应用程序也可以获益于 OSGi 的模块化特性 , 比如您需要把应用程序打包成逻辑功能独立的 jar 包,并且只部署真正需要用到的某些 jar 包来避免系统资源浪费,那么 OSGi 就是一个绝佳的选择。
OSGi 的设计和开发完全满足模块化软件的设计和开发标准,所以每一个 OSGi 的 Bundle 都是一个完全符合标准的模块。正如我们在第一部分所讲到的模块的第二个优势一样,OSGi 的 Bundle 具有优异的可重用性特性。一旦我们开发好一个 Bundle 后,这个 Bundle 就可以很容易的被重用到其他的 OSGi 软件开发过程中,即节省了资源,又提高了软件开发的效率。
传统的 Java EE 架构中,对于一个依赖于很多第三方程序库的企业应用程序,通常的做法是将 EAR 中每个应用程序需要的第三方程序库都加入到 EAR 中。虽然这种做法使得我们很简单的将 EAR 由原有系统移至另一个系统,不需要额外考虑它所依赖的程序库,但是也带来两个问题。
- 随着应用程序的扩展,EAR 文件越来越大,并且文件内部所包含的模块中存在引用同一个第三方程序库,因此而引起冗余的情况。也就是说,内存中可能同时包含某些第三方程序
库的重复备份。
- 因为应用程序内只能支持某个类的单一版本,如果多个第三方程序包依赖于不同版本的
公共类库,就会出现版本冲突的问题。
OSGi 通过 Bundle 存储库很好的解决掉上述问题,有了 Bundle 存储库之后,EAR 中只包含特定于应用程序的模块,所有的依赖公共类都放到 Bundle 存储库中进行统一管理。并且 Bundle 存储库可以管理多个 Bundle 的不同版本,应用程序通过在元数据中来指定依赖于 Bundle 存储库中某一 Bundle 的具体版本,从而来使用特定版本的公共类。
传统的 Java 程序使用全局的 Classpath 来定义依赖关系,如果 Classpath 没有正确设置,或者 JAR 包被移动到一个不能满足其所有依赖项要求的新环境,就可能遇到 ClassNotFoundExceptions,OSGi 要求开发人员在设计 Bundle 的时候,就在元数据中指定该 Bundle 的依赖项。
在 WebSphere Application Server V8 中,当每个 Bundle 启动时,WAS 自带的 OSGi 框架解析器会为每个 Bundle 启动一个单独的类加载器,如果某个 Bundle 有一个无法解析的依赖项,该 Bundle 将不会被启动,从而避免了上诉错误的发生。
所以,对于开发人员来说,在开发模块时,只需要简便地定义好这些依赖关系即可。OSGi 应用运行时会保证能够解析到正确版本的依赖包,并提供合适的包给其它模块。
在 OSGi 框架中,还是使用跟 Java EE 架构一样的 web 容器、事务管理器、JPA 实现等等,因此当类被加载后,在运行时性能方面 OSGi 架构和 Java EE 架构是一样的。
在 WebSphere Application Server V8 中,管理人员可以在不重启 OSGi 应用的情况直接更新某一个模块,这一点是非常有用的,尤其是当这个应用非常大的时候。
比如在 100 个节点上去更新一个 100Mb 的应用,在 JEE 架构中所带来的时间开销是非常大的。尽管更新的只是某单一的模块,也需要花费相当于重新安装的时间。然而在 OSGi 应用中,您可以选择只更新这 100MB 应用中的某一模块,比如 10MB 的业务模块,在 100 个节点上更新某一 10MB 模块要比更新整个 100MB 应用要快得多;而且在 OSGi 架构中,更新局部模块不需要重启整个应用。这样就大大简化了管理员的工作,节省时间。
为了使管理员可以轻松的享用到这一特性带来的好处,WAS 版本 8.0 提供了图形化控制台的方式来管理 Bundle 的动态更新,管理员只需点击几个按钮,就能完成对大规模企业应用的动态更新。
一个 OSGi 服务就是注册到 OSGi 框架中的一个 Java 对象,向服务注册表注册自身的一个或多个接口。OSGi 服务的动态性是指当一个 Bundle 被 OSGi 框架发现并做为一个服务启动后,该服务可以在任何时候变的可用或不可用。OSGi 提供了相关的技术和实用的类库,可以帮我们实现动态服务。OSGi 框架包含一个中央服务注册表 (Centralized Service Registry)(见图 1),遵循“发布 - 查找 - 绑定”的模型,该模型是实现动态服务的基础。
图 1. OSGi 服务注册表
WebSphere Application Server V8 完全遵守最新的企业级服务标准 Blueprint Services,使得服务的查找、发布和绑定变的更加容易,也更有效率。让管理人员真正体会到模块的“热插拔”所带来的好处。
WebSphere Application Server V8 提供 OSGi bundle 存储库来简化应用程序的部署。WAS 可以使用外部 bundle 存储库或者内部 bundle 存储库。这些 bundle 存储库可以用来减少硬盘和内存使用空间。比如对于每个 Java EE 应用程序,它们之间的模块是完全独立的,这样就会出现被引用的同一模块在不同的应用程序里重复存在,存在冗余,并且不利于版本维护,也带来了内存等资源的消耗。
在 OSGi 应用程序里面,所有的模块都是可以共享的,这样对安全性方面也存在一定的隐患。而 WebSphere Application Server V8 提供的 bundle 存储库 ( 内部存储库和外部存储库 ) 可以把这两者的优点集合起来,使得应用程序之间既存在一定的独立性,也能够共享资源,提高整个系统的性能。如下图所示,WAS 将不同应用程序所特有的模块和不同应用程序公有的模块分别放在两个不同的 OSGi 框架中进行处理,即做到了不同应用程序的隔离,也实现了不同应用程序之间的共享。
图 2. WAS V8.0 中 OSGi 共享库的实现机制
懒惰对于软件来说其实是一个褒义词,OSGi 提供了多种方法使得只在需要的时候才去做事情。比如说,bundles 可以被马上启动,也可以配置成只有被其他 bundle 调用时才启动。服务可以先添加到注册表里,只有当被调用时才被启动,从而极大地减少运行时的开销。比如一个大型的 OSGi 应用包含 100 个 bundles,如果都把这些 bundles 启动起来,会极大地消耗资源,比如 CPU 和内存,而且启动的速度也会变慢。在安装时,可以只把核心 bundles 启动,让其它 bundles 仍处于未启动的状态,然后根据需要,在运行时再去启动那些被调用的 bundles,从而减少对运行时的开销。
根据用户对 OSGi 功能的反馈,以及用户对现有 WebSphere Application Server 的兴趣,我们可以预见,作为模块化软件开发最重要的技术,OSGi 将会越来越受到企业级软件用户的的欢迎。Java EE 的开发人员也会越来越多的选择 OSGi 技术去开发最新的软件,我们也期待 OSGi 在企业级软件开发过程中有更好的表现。
学习
-
WebSphere Application Server V8 信息中心:了解更多 WebSphere 产品的信息。
-
OSGi 联盟:了解最新的 OSGi 规范。
-
>Rational Application Developer 8.0.3 信息中心:是 Rational Application Developer 8.0.3 的在线用户手册,其中包含 OSGi 应用程序开发的详细步骤,还包含 OSGi 应用开发的教程。
-
IBM developerWorks 中国 WebSphere 专区:为使用 WebSphere 产品的开发人员准备的技术信息和资料。这里提供产品下载、how-to 信息、支持资源以及免费技术库,包含 2000 多份技术文章、教程、最佳实践、IBM Redbook 和在线产品手册。
获得产品和技术
- 最受欢迎的 WebSphere 试用软件下载:下载关键 WebSphere 产品的免费试用版。
- IBM developerWorks 软件下载资源中心:IBM deveperWorks 最新的软件下载。
- IBM developerWorks 工具包:下载关键 WebSphere 最新的产品工具包。
讨论
- 加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。
- 加入 IBM 软件下载与技术交流群组,参与在线交流。