【目录】- 【热插拔与动态支持】-【概念】
“热插拔和动态支持”应该算是OSGi.NET最有趣,最Cool的一个功能,官方文档是这样介绍的
1) 热插拔:所有的模块都可以被动态的添加和卸载。
2) 生命周期:模块生命周期状态由“已安装、已解析、正在启动、已激活、正在停止、已停止、已卸载”组成,每一个生命周期状态下,模块提供的功能都可能不同。
3) 动态:当模块执行任何生命周期操作时,模块会动态的想外界暴露或者隐藏它提供的功能,比如动态提供服务、扩展或者其它功能。
4) 远程部署:支持模块远程部署,比如远程安装、启动、停止和卸载模块,或者订阅模块仓库中模块变更并同步。
正如我们前面一直强调的,理想情况下,OSGi.NET的模块都是一个个可独立,且无任何逻辑或物理联系的个体,就像一块块的积木,可通过多种搭配方式进行组装和卸载。“热插拔”就是在这种大前提下实现模块的“在线(live)”,或着说,“动态(Dynamic)”添加和卸载,这使得“远程部署”成为可能。上一节“模块可扩展支持”中的小结就很好的展示了热插拔特性。
注意这里的“远程部署”
1) 它是在线的,而不是离线,也就是不需要将程序关闭,用户可在正常情况使用下,部署模块
2) 由于ASP.NET的特殊性,需要将“运行时”重启,但Web本身就是非持久性连接,处理恰当的话,对最终用户影响不是很大。WinForm不受影响。
当然,OSGi.NET对模块的处理并不是安装和卸载这么简单,他有前面我们已经提到过的“生命周期管理”,具体流程参照官方图例
对上面每个模块的“状态”,都有其特定的用意,稍后我们会通过实例做展示。这里“停止(Stopping)”和“卸载(Uninstalled)”需要稍加说明一下,停止是模块将自己的生命进程交还给运行时环境前最后的一个状态,而卸载是运行时环境将模块结束前的最后一个状态。简单来说
1) 安装、解析、卸载只能由运行时环境来管理,而启动、激活、停止是模块本身可一同参与的
2) 停止的模块依然在运行时环境管理中,只不过模块不能再管理自己的状态,但其他模块可通过运行时环境对它进行控制
3) 卸载的模块,在下次重启并删除之前,依然在运行时环境管理中
4) 安装和启动,类似卸载和启动
5) 解析和具体的模块加载过程,可参照前文“模块化和插件化”实例部分
“动态”特性其实我们在前面的“面向服务架构支持”和“模块可扩展支持”中已经见识过了,看看官方给的具体过程示意图
接下来的实例中,我们将通过一个具体的例子来看看可能比较关注的“动态性配置”和远程部署。
【目录】- 【热插拔与动态支持】-【实例】
我们继续使用上一节“模块可扩展支持”的实例,这一次不需要写什么代码,只需要少量的编辑一下XML。
OSGi.NET为每个模块提供一个专门的配置来设定它的初始运行状态,双击OSGi.NET.APEDecoderPlugin的Manifest.xml文件,可以看到如下界面
1) “当框架激活时立即启动Bundle”,这个选项如果勾选上的话,则这个模块(Bundle)会按照安装、解析、启动、激活顺序执行。如果不勾选,则到安装后就停止了,如果这个模块还被其他模块依赖,则会忽略这个配置,直接运行到激活。还需要注意,每次更改这个选项时,须将此模块中的persistent.xml删除掉,否则无法看到效果。persistent.xml用来记录最后一次的初始化状态。
a) 我们来试试不勾选它,来看看运行效果
可以看到APE选项并没有出现,再打开“远程管理工具”,输入字母l
OSGi.NET.APEDecoderPlugin的状态为Installed,安装。我们继续输入s 5
回到主程序,点击回车
APE便回来了。
b) 当然你可以通过编码的方式将它启动起来,例如
2) 当存在“激活器”时,还可以选择“晚激活,即当Bundle的类被加载是再激活”。这个有点儿类似.NET的晚激活策略,也就说如果勾选,则模块会从安装到解析便停止执行,而当别的模块需要引用它的某个类时会自动继续执行启动和激活,理论上可以减少不必要的消耗。
接下来我们继续使用这个例子,来演示一下如何完成“远程部署”
1) 首先,我们将整个OSGi.NET.APEDecoderPlugin文件夹压缩成zip包后删除这个文件夹。压缩包放到一个稍后可以访问到的位置,如D:\
2) 运行起整个主程序,默认的APE选项将不会出现。接着我们打开“远程管理工具”,输入字母l,这时也没有OSGi.NET.APEDecoderPlugin。保留着主程序不要关闭它。
3) 在远程管理工具里输入i "OSGi.NET.APEDecoderPlugin" "D:\OSGi.NET.APEDecoderPlugin.zip" "D:\cnblogs.com\OSGi.NET\Demo4\OSGi.NET.AudioPlayerShell\OSGi.NET.AudioPlayerShell\bin\plugins\FormatTypes\Lossless\OSGi.NET.APEDecoderPlugin",并回车,可以看到提示已经安装成功
再次输入字母l
OSGi.NET.APEDecoderPlugin处于安装(installed),而非激活(Active),还需要启动它,继续输入s 6
OSGi.NET.APEDecoderPlugin启动成功,在主程序中点击回车
APE选项出现了。
【目录】- 【热插拔与动态支持】-【小结】
热插拔和动态支持本身就是最开始提到的“模块化和插件化”的最佳体现。基于模块化和插件化才使得“热插拔和动态支持”成为可能。
面对前阵子有人提出了对OSGi的质疑,想说
1) 程序员都这样,当你想使用某种技术和思想的时候,你会想尽办法去说它如何如何好,找很多相关的资料来证明它的好,反之,你不喜欢它也是一样,你会研究,反驳等等,这其实是件好事情,让更多人了解它的多方面OSGi和其他技术一样,都有他的适用场景和最佳实践方法,在宣传人员的嘴里你是很少听他们说这些的,反之,在反驳的时候你会听到很多他“不怎么”适合的地方。
2) 一种技术或者一种思想方法适合不适合我们,并不会影响它的本质,它是好,还是坏,都是通过我们的质疑,质疑,反复质疑中建立起来的,但他如何的好,如何的坏都是我们自己去实践和体会的
3) 当大多数人都在追捧某件技术或者思想的时候,你可以看到很多优秀的想法,或许也会看到不少糟粕,但这种认知不会是一尘不变的,他会随着我们对问题的深入了解而随时改变。与此同时,技术和思想也在不断放生变化,去适应大多数人的需求,这种变化总是超前与我们对它的定论,这才是学习技术的美妙之处
针对质疑中的一个论点,“动态替换模块,前提是不丢失运行时数据,否则就是空谈。OSGi 官网、文档从未提到可以替换正在忙碌中的模块。问题是,如果是替换不忙的模块,非要用 OSGi 么?我可以把应用系统停下来,更新版本,重新启动新版本软件,然后喝杯咖啡,眯会儿眼睛,...”,可以这么看
1) 丢不丢数据、模块忙不忙取决你的设计策略,该不该更新、什么时候更新、怎么更新属于你的部署策略,总体来说部署策略受设计策略约束,所以好的设计策略可以让看起来不太可能的部署策略得以实现。当然,最重要是看你有没有这种需求。
2) 部署策略也有很多种,人工复制粘贴,自动化脚本,补丁程序等等都可以,技术上没有什么优劣,但用户体验上却有不同。有的情况下,你快递给用户一个U盘,让他自己复制再粘贴,也是可是被接受的,但如果客户端是在成千上万台分布全球的PC上时,就不能不考虑成本问题了
3) 即便都是统一的在线更新策略,典型的就是Windows Update,它也分更新完,需要重启系统和不需要重启系统。当然你可以设置你的更新策略是必须全部重启更新。但对于用户来说减少了一次不需要的重启,是不是用户体验会更好些呢?毕竟有些更新的确不需要重启的
4) 其次,用户最看重的必然是功能和体验,而作为产品的研发设计人员,您是否应该考虑不仅仅是完成某些功能,而且能让你这个功能有着最佳的体验?技术上对我们来说不是问题,问题是这里不完全是技术。如果需要考虑OSGi的时候,肯定不能只关注他技术上实现了什么,还得知道这种技术能改善什么
5) 需要强调的是,OSGi并不是一个简单的模块化框架,还是一种思考问题和解决问题的方式。既然是方式,那他就是条条大路通罗马中的一条,不需要高估他,也不需要低估他,因为他自有他合适的地方
在稍后的“高级话题”中,我们会结合具体的实例来继续探讨,如何更好,更恰当的运用OSGi.NET来分析和解决我们的问题。