质疑 OSGi 的作用

2012-07-13 17:09

 

最近和别人在 cnblogs 上就 OSGi 的作用进行了讨论,由于那里面的人,只会从网上抄袭 n 年以前的网上套话,很少有自己的分析、见解,无法展开讨论。

 

特此写搏客文章,阐明自己的观点,同时希望和更多的人,对此技术,进行讨论。

OSGi 是由 1999 年成立的 OSGi 联盟提出的一个开放的服务规范,最初的目的是为嵌入式设备。

据我从网上搜索到的资料,目前 OSGi 主要用于 嵌入式设备,及无数据库的单机版程序,比如 Eclipse。

 

OSGi 目前在用的功能,主要是把某个模块(OSGi 有个特别的名次,叫 bundle),加载进内存、运行、然后由总控程序决定什么时候从内存中卸载。

这一点很容易理解,Java 中有 ClassLoader 用于把 Java 类加载进内存,但并没有特别的手段,把已经加载进内存的类,从内存中去掉。而像 Eclipse 这样的程序,功能较多,比如有 jsp 编辑器、java 编辑器、XML 编辑器,并不需要一启动,都把这些编辑器对应的类,加载到内存中。可以延迟加载,用到的时候,加载进 JVM 内存。延迟加载在 Java 中并不需要特别处理,因为默认就是如此:没有用到的类不会加载进内存,用到的类,用到时才加载进内存。

但 Java 中并没有特别的手段,去卸载已经运行过但现在不用的类。如果我们先打开一个 java 文件,Eclispe 启动 java 编辑器,然后我们关闭 java 文件,打开一个 CSS文件,Eclispe 启动 CSS 编辑器,此时应该把 java 编辑器从内存中去掉,但 Java 本身没有提供这种功能。当然我们可以期待 Sun/Oracle 公司,未来可以在 Java 中提供这个功能。

Eclipse 使用 OSGi 来实现不用的插件,从内存中卸载掉,这点不错,可以节省内存。但是我们大部分人的应用,并不需要这么做。因此,OSGi 这个技术,并不适合大多数应用。

很奇怪的是,很多 OSGi 爱好者,盲目相信 OSGi 可以动态更新版本。据我了解,Eclipse 如果通过网络更新插件,是需要整个 Eclipse 重新启动的,并没有像这些爱好者所说的那样,可以自动更新、无需重新启动。也许,只要更新的是目前不用的模块,可以做到“自动更新、无需重新启动”。

 

汽车的音响不会同时播放 CD 和收音机,因此从听 CD 换成听收音机的时候,汽车控制程序可以把CD对应的 bundle 进行 unload。但是,从未听说哪个汽车厂商说,可以在汽车高速转弯的时候,汽车里面的控制程序正在运行制动力智能分配,你这时候可以通过网络,更新“制动力智能分配”这一部分软件。

Eclipse 更新插件后,重新启动用时几分钟,大部分人可以接受,不接受大不了暂时不升级;汽车控制程序在高速转弯时,绝大多数人都不会选择在这个时候更新汽车软件,除非脑子不正常,一般都会选择在停下来,熄火,或者挂空档、驻车挡,喝杯咖啡,让 4S 店去升级汽车软件。也就是说, OSGi 爱好者口中号称的 OSGi 在 Eclipse、汽车软件中的动态升级,不过如此。

 

动态替换模块,前提是不丢失运行时数据,否则就是空谈。OSGi 官网、文档从未提到可以替换正在忙碌中的模块。问题是,如果是替换不忙的模块,非要用 OSGi 么?我可以把应用系统停下来,更新版本,重新启动新版本软件,然后喝杯咖啡,眯会儿眼睛,...

还有人提到电信软件的动态替换,电信软件的模块是不忙的模块么?

 

有数据库的应用,可以借助数据库来解决模块之间的依赖问题:

模块 A 从表 1 读数据,处理后 insert 到表2,模块 B 从表 2 读数据,处理后 insert 到表3。表面上看来,两个模块互相依赖,但是如果我们用独立的 java.exe 来运行模块 A、模块 B,则可以达到 模块 A 关闭几分钟然后启动,不影响模块 B。

也就是说,有数据库的应用,模块之间的依赖,有额外的办法解决,而这个办法,不需要制定什么标准,不需要学习什么新知识,总之一个词:容易!

 

这也是目前 OSGi 只用在无数据库系统中的原因。可惜很多人看不到这一点。

 

这里有一段搞笑的话(http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-osgi/):


除了模块化以及面向服务编程之外,OSGi的另一个重要特点是其动态性,Bundle以及Bundle提供的服务可以随时消失或者重新加入,而其它使用服务的Bundle可以感知服务是否可用,并动态地改变自己的行为。
		

搞笑之处在于,“而其它使用服务的Bundle可以感知服务是否可用,并动态地改变自己的行为。”,如果我要调用一个发送传真的模块,结果感知“发送传真模块”暂时不可用,程序接下来能做什么?等?骂娘?哭?嚎叫?怎么做都不合适,尴尬!

在不用 OSGi 的情况下,我不需要“感知”其他模块是否可用,直接调用,出错就报错。程序逻辑清楚、简单。加入 OSGi 后,我需要“感知”其他模块是否可用,还需要“动态地改变自己的行为”,复杂,麻烦,怎么做都不舒服!如果我每个模块,都需要“感知”其他各个模块是否可用,都需要决定如何处理各种额外情况,何等几何级的复杂!这哪是人干的活!这就是 OSGi 的麻烦!

我觉得,OSGi 目前只做了一件事:处理 Java 做不好的 unload class 功能。考虑到现在内存如此便宜,4G 内存满天飞,手机内存也稳步增长,其它嵌入式设备的内存,也在增长。是否一定要 unload 掉不用的类,好像也不是很必要!毕竟不是很多软件,能把计算机内存撑爆的。

 

很奇怪的是,现在很多人在吹 OSGi,觉得这是一个万金油,哪里都可以用。真不知道这些人是怎么想的。

另外,即使是好用的东西,也要看使用成本。奔驰车好,能让所有人去买奔驰?OSGi 程序开发调试困难,学习也花时间,难道可以忽略不计?

至于 OSGi 解决模块化的依赖问题,更是胡闹。大不了我每个 “模块” 单独用一个 java.exe 来 运行,还有依赖问题么?有什么必要用 OSGi?

 

补充,很多人回复中都提到 Eclipse ,好像 Eclipse 使用 OSGi 是因为 OSGi 很强大什么的,不过,从这篇文章中,可以看出,不是这么回事:

OSGi: Eclipse的根基

http://www.builder.com.cn/2007/0929/528796.shtml


有很多人问Eclipse为什么要兼容OSGI规范而不是其他的规范呢?
在Eclipse被捐赠出来以前,Eclipse由OTI来开发,其目标是开发一个嵌入式Java软件的开发平台。互联网上现在仍然由很多的连接指向 Visual Age Micro Edition (VAME). 这也是SWT被构思的一个原因,他们想将SWT使用在嵌入式设备中的用户界面。这种渊源关系解释了当时为什么选择OSGI规范。
另外一个原因是除了OSGI没有其他的规范...

...
		

 

2012/7/26, 再补充:

在 http://zh.wikipedia.org/wiki/OSGi 上,写明:“OSGi原先关注于服务网关,其实可用于多个方面。现在OSGi规范已经用于从移动电话到开源的Eclipse(其中包括了与IBM的OSGi框架SMF兼容的开源版本)。 OSGi服务平台的应用包括:服务网关、 汽车、移动电话、 工业自动化、建筑物自动化、 PDA 网格计算、娱乐(如iPronto)、和 IDE。”。只字未提数据库应用、企业应用。在英文版本的 http://en.wikipedia.org/wiki/OSGi 页面上,大同小异。

迄今为止,有什么大公司,把 OSGi 用在一个有数据库的系统中么?没有!不明白那么多人糊里糊涂的把OSGi 用在自己的一个有数据库系统中,是哪根神经不对了。

 

 

欢迎转载,转载请注明出处: https://www.zheguisoft.com/staff_blogs/jacklondon_chen/2012, 及 https://www.cnblogs.com/jacklondon/archive/2012/07/13/2590547.html