OpenDaylight中的OSGi

描述

从写单个类的打印Hello World小程序到OSGi模块化开发,确实存在较大的难度,本文将从模块化、OSGI模型以及OSGI在OpenDaylight中的应用等方面进行介绍。

一、模块化

我们学习Java语言时,最初写的程序便是在控制台打印Hello World,此时,我们写的代码放在一个类中;慢慢地,我们编写的代码需要放在几个的类时,我们就要考虑如何设计类与类之间的关系,你需要面向对象的设计原则和模式;工作中我们要做一个小项目,就可能涉及到数百个类了,我们会根据不同的业务职责将这些类进行逻辑上的划分,分隔不同的小模块,每个小模块赋予相应的职责,也就是将一个系统分解为多个较小的互相协作的单元,并设定单元之间的边界来改善系统的维护性和封装性。大致过程如下图①②③所示:

模块化

至目前为止,我们所做的事情是对类进行了逻辑的包装,而实质上并没有对类进行物理隔离。通常情况下,软件在初始构建时,并不是很复杂,但随着时间的推移、业务特性的增加、不规范的代码调用以及为赶进度而忽略架构的设计,就使得软件变得复杂起来,甚至极难维护。如同双11爆仓时凌乱不勘的场景:

模块化

图片来自互联网

那么如何降低软件的复杂性呢?生活中的货物运输或许是一个很好的借鉴例子,我们将零散的货物打包在一起,形成封闭的空间;然后,通过标准的接口装载到集装箱运输船。

模块化

事实上,早在1972年国际软件工程大师David Parnas在《On the Criteria To Be Used in Decomposing Systems into Modules》一文中就提出了模块化编程的思想:“每项任务构成一个独立的、特有的程序模块。实现时,每个模块及其输入/输出都有确定含义的......系统以模块化的方式进行维护”,其实质就是软件模块划分应该以基于信息隐藏为目的,以职责划分为手段,从而封装变化。联想到集装箱的例子,软件的模块可以类比为集装箱,如下图所示:

模块化

我们现在正式介绍软件模块,在《Java应用架构设计 模式与OSGI》一书中进行了描述:软件模块是可部署的、可管理的、原生可重用的、可组合的、无状态的软件单元,它为用户提供了简洁的接口。

① 可部署:模块是一个独立的部署单元,它能够与其他软件模块共处。EAR、WAR以及JAR文件。

② 可管理:在运行时,模块可以进行安装、卸载以及更新。实体样例:EAR、WAR以及JAR文件。

③ 原生可调用:模块总是原生可调用的。也就是说,模块暴露的操作是通过直接调用方法触发的。

④ 可组合:一般指的是粗粒度的模块是由细粒度的模块组成的。

⑤ 无状态:特定版本的模块只会存在一个实例。

由前面的分析可知,Java模块化支持局限于细粒度的面向对象支持,需要有更高抽象粒度的模块。OSGi便是Java模块化需求其中一个解决方案。

一、OSGi

  1. 什么是OSGi?

OSGi(Open Services Gateway initiative,开放服务网关协议)是由 1999 年成立的 OSGi 联盟提出的一个开放的服务规范,最早用于嵌入式设备。在2004年,Eclipse发布于基于OSGi的运行时模型,把 Equinox 作为底层运行平台。借助于Eclipse,OSGi在商业化软件企业中得到广泛的关注。现已广泛应用于移动设备、桌面应用以及企业应用服务器。

  1. OSGi框架

OSGi框架是应用的执行环境。OSGi框架规范定义了OSGi的行为,现已有Apache Felix、Eclipse Equinox以及Knopflerfish等多个开源实现。OSGi的分层架构如下:

模块化

模块层定义了模块,称为Bundle,体现为一个JAR文件,由类文件、资源文件和MANIFEST.MF组成。和普通的jar文件唯一不同的就是MANIFEST.MF文件的内容,基本上都是标识Bundle的属性,Import-Package声明了请求JAR文件中的代码所需要的外部包。其文件样例为:

模块化

生命周期层定义了动态安装和管理Bundle,即可以在框架中安装和卸载bundle,而不需要重启应用进程。

服务层定义了面向服务的应用编程模型,涉及面向服务的发布、查找和绑定交互模式:服务提供者将服务发布到服务注册中心,然后服务请求者通过搜索服务注册中心,查找可供使用的服务。这种机制称为VM中的SOA。事实上,服务就是Java接口。

模块化

3.OSGi生态

模块化

4.Bundle交互

了解了OSGi基础知识后,我们来看下Bundle交互的实现方式:

(1) Export和Import:即通过Package的Export和Import来进行。服务提供者Bundle对外Export自己的package,而服务请求者则根据业务需要Import外部的Package;

(2) service:服务提供者Bundle对外提供Service,而服务请求者查找Service。而提供Service的方式又有:

① 通过BundleContext(Bundle上下文)来提供和获取;

② 通过Declarative Service来实现;

③ 通过Blueprint来实现;

在这里,我们重点介绍第3种方式--Blueprint。Blueprint提供一个依赖注入框架来实现OSGI,并在OSGI Compendium R4.2里被OSGI组织标准化。Blueprint的强大之处在于即具有Spring强大且非侵入性的企业级编程模型又具有OSGi的动态性、模块化的特性。

Bundle间的交互使用类似Spring Bean的方式配置定义,Blueprint的XML文件定义和描述不同Bundle的组装。一个简单的Blueprint示例如下:

模块化

XML文件的命名空间标识blueprint 1.0.0版本。顶级的blueprint元素标识XML文件作为一个blueprint模块来定义;reference元素标识从OSGi服务注册中心为组件获得一个服务;bean元素标识与Spring Bean相同的含义。

一、OSGi在OpenDaylight中的应用

Java模块化的局限和OSGi框架的模块化标签,使得Java和OSGi走在了一起,进而增加了Java模块化开发的能力。

作为SDN控制器,OpenDaylight使用了Java语言编写,SDN控制器本身的功能与协议繁多导致了其子项目众多,如何更好地按需动态加载所需的项目成为技术选型的一个重要因素。而OSGi的如下特性也使得其在OpenDaylight中发挥很大的作用:

① 将一个程序打包成逻辑上独立的JAR文件,并且只部署那些某个安装所需要的部分。

② 将一个程序打包成逻辑中独立的JAR文件,声明哪些代码可以被其他JAR文件访问,并且强调可见性。

③ 为程序提供一个插件式的扩展机制。OSGi模块化特别适合提供强大的扩展机制,包括支持执行时的动态性。

OpenDaylight采用了OSGi框架之后,那开发一个应用程序的流程又是怎样的呢?下面给出一般方法:

① 根据应用的业务场景设计Bundle,并设计Bundle的服务;

② 使用IDE实现Bundle,配置Blueprint容器XML文件;

③ 打包和部署Bundle的JAR文件;

④ 启动类似Karaf之类的部署环境,并根据业务需要安装Bundle。

事实上,OpenDaylight不仅采用了OSGi框架,而且还使用了Apache Karaf这个企业级容器,下篇文章我们将探讨Apache Karaf的基础知识。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分