我在维基百科和其他网站上读到过OSGi,但我没有真正看到大局。它说它是一个基于组件的平台,并且您可以在运行时重新加载模块。同样,到处都给出的“实际示例”是Eclipse插件框架。
我的问题是:
OSGi清晰而简单的定义是什么?
它能解决什么常见问题?
所谓“常见问题”,我指的是我们每天都要面对的问题,比如“OSGi能做些什么来让我们的工作更高效/有趣/简单?”
为清晰起见,经过编辑。OSGi页面给出了一个比我更好的简单答案
在单个应用程序结构中,比如Eclipse IDE,在安装新插件时重新启动并不是什么大问题。完全使用OSGi实现,您应该能够在运行时添加插件,获得新功能,而完全不需要重新启动eclipse。
同样,这不是每天都要做的大事,只是应用程序的小用途。
但是,当你开始研究多计算机、分布式应用框架时,这就是它开始变得有趣的地方。当关键系统必须有100%的正常运行时间时,热插拔组件或在运行时添加新功能的能力非常有用。当然,现在大多数情况下都有这样做的能力,但是OSGi正试图将所有东西捆绑到一个具有公共接口的漂亮的小框架中。
OSGi能解决常见问题吗,我不确定。我的意思是,它可以,但对于更简单的问题,开销可能不值得。但是当您开始处理更大的、网络化的应用程序时,需要考虑这一点。
我发现OSGi有以下好处:
这样,您就可以将应用程序构建为一组按需加载的版本化插件构件。每个插件都是一个独立的组件。就像Maven帮助您构建构建,使其可重复,并由创建它的工件的一组特定版本定义一样,OSGi帮助您在运行时完成这一点。
我不太关心OSGi模块的热插拔性(至少目前如此)。这更多的是被强制的模块化。在类路径上没有数百万个“公共”类可以随时使用,这很好地避免了循环依赖:你必须真正考虑你的公共接口——不仅仅是从java语言结构“公共”的角度考虑,而且是从你的库/模块的角度考虑:你想让其他人可用的组件(确切地)是什么?为了实现你的功能,你真正需要(其他模块的)接口是什么?
这很好,热插拔是附带的,但我宁愿重新启动我通常的应用程序,而不是测试所有的热插拔组合…
它还被用于在移动端带来额外的中间件和应用程序的可移植性。移动端可用于WinMo, Symbian, Android等。一旦与设备功能集成,就会出现碎片化。
对于使用Java的每个人来说,有很多好处(我现在只提醒了这些)。
至少,OSGi让您考虑到模块化、代码重用、版本控制以及项目的一般管道。
在OSGi上让我抓狂的几件事:
1)实现和它们的上下文加载器有很多怪癖,并且可能有点异步(我们在confluence中使用felix)。与纯spring(没有DM)相比,[main]几乎运行了所有同步。
2)热加载后类不相等。例如,在hibernate上有一个tangosol缓存层。它被Fork.class填充,在OSGi作用域之外。你热加载了一个新的罐子,Fork没有改变。Class[Fork] != Class[Fork]。由于相同的潜在原因,它也会在序列化过程中出现。
3)集群。
您可以解决这些问题,但这是一个非常麻烦的问题,并且会使您的体系结构看起来有缺陷。
对于那些为热插拔做广告的人。OSGi的#1客户端?Eclipse。Eclipse在加载包之后做什么?
它重新启动。
〇降低复杂度使用OSGi技术开发意味着开发包:OSGi组件。捆绑包是模块。它们对其他捆绑包隐藏了内部信息,并通过定义良好的服务进行通信。隐藏内部意味着以后可以更自由地进行更改。这不仅减少了错误的数量,还使包的开发更简单,因为大小正确的包通过定义良好的接口实现了一项功能。有一个有趣的博客描述了OSGi技术在开发过程中的作用。
OSGi组件模型使得在应用程序中使用许多第三方组件非常容易。越来越多的开源项目为OSGi提供了现成的jar。然而,商业库也可以作为现成的包使用。
OSGi框架是动态的。它可以动态地更新捆绑包,服务可以来来去去。习惯于更传统Java的开发人员认为这是一个非常有问题的特性,没有看到它的优势。然而,事实证明,现实世界是高度动态的,拥有可以来来去去的动态服务使得这些服务与许多现实世界场景完美匹配。例如,服务可以为网络中的设备建模。如果检测到设备,则注册该服务。如果设备消失,则该服务未注册。与此动态服务模型相匹配的现实场景数量惊人。因此,应用程序可以在自己的域中重用服务注册中心的强大原语(使用表达性筛选语言注册、获取、列出,以及等待服务出现和消失)。这不仅节省了编写代码的时间,还提供了全局可见性、调试工具以及比专用解决方案实现的更多功能。在这样一个动态环境中编写代码听起来像是一场噩梦,但幸运的是,有一些支持类和框架可以消除大部分(如果不是全部的话)痛苦。
OSGi技术不仅仅是组件的标准。它还指定了如何安装和管理组件。许多包都使用这个API来提供管理代理。这个管理代理可以简单到命令shell、TR-69管理协议驱动程序、OMA DM协议驱动程序、Amazon EC2的云计算接口或IBM Tivoli管理系统。标准化的管理API使得在现有和未来的系统中集成OSGi技术变得非常容易。
OSGi组件模型是一个动态模型。可以安装、启动、停止、更新和卸载包,而不会导致整个系统瘫痪。许多Java开发人员不相信这可以可靠地完成,因此最初没有在生产中使用它。然而,在开发中使用它一段时间后,大多数人开始意识到它实际上是有效的,并显著减少了部署时间。
OSGi组件模型从头开始设计,以允许组件的混合和匹配。这要求指定组件的依赖关系,并且要求组件生活在其可选依赖关系并不总是可用的环境中。OSGi服务注册中心是一个动态注册中心,包可以在其中注册、获取和侦听服务。这个动态服务模型允许包找出系统上可用的功能,并调整它们可以提供的功能。这使得代码更灵活,更能适应变化。
包和服务是OSGi环境中的第一类公民。管理API提供了对捆绑包内部状态的访问,以及它如何连接到其他捆绑包。例如,大多数框架提供了一个命令shell来显示这个内部状态。可以停止部分应用程序以调试某个问题,也可以引入诊断包。OSGi应用程序通常可以使用实时命令shell进行调试,而不是盯着数百万行日志输出和漫长的重新启动时间。
版本控制, OSGi技术解决JAR地狱。JAR地狱的问题是库A与库B;version=2一起工作,但库C只能与库B;version=3一起工作。在标准Java中,您就不走运了。在OSGi环境中,所有的包都经过了严格的版本控制,只有能够协作的包才被连接到同一个类空间中。这允许bundle A和C使用它们自己的库工作。尽管不建议设计带有此版本问题的系统,但在某些情况下,它可以挽救生命。
OSGi API非常简单。核心API只有一个包和不到30个类/接口。这个核心API足以编写包、安装它们、启动、停止、更新和卸载它们,并且包括所有侦听器和安全类。很少有API能够为如此少的API提供如此多的功能。
OSGi Release 4框架可以在大约300KB的JAR文件中实现。对于通过包含OSGi而添加到应用程序中的功能而言,这是一个很小的开销。因此,OSGi可以在各种各样的设备上运行:从非常小的设备到小型设备,再到大型机。它只要求运行一个最小的Java VM,并且在上面添加了很少的内容。
快 - OSGi框架的主要职责之一是从bundle中加载类。在传统Java中,jar是完全可见的,并放置在一个线性列表中。搜索类需要搜索这个列表(通常很长,150个也很常见)。相反,OSGi预先连接捆绑包,并确切地知道每个捆绑包是哪个捆绑包提供的类。缺乏搜索是启动时显著的加速因素。
懒惰,软件中的Lazy是好的,OSGi技术有许多适当的机制,只在真正需要的时候做事情。例如,包可以被急切地启动,但也可以配置为仅在其他包使用它们时才启动。服务可以注册,但只有在使用时才创建。规范已经优化了几次,以支持这种可以节省大量运行时成本的懒惰场景。
安全- Java在底层有一个非常强大的细粒度安全模型,但在实践中却很难配置。结果是,大多数安全的Java应用程序只能在两种情况下运行:没有安全性或功能非常有限。OSGi安全模型利用了细粒度的安全模型,但通过让包开发人员以易于审计的形式指定所请求的安全细节,而环境的操作员仍然完全负责,从而提高了可用性(以及增强了原始模型)。总的来说,OSGi可能提供了最安全的应用程序环境之一,在缺少受硬件保护的计算平台的情况下仍然可用。
OSGi环境中的应用程序(包)留给它们自己。他们几乎可以使用VM的任何工具,而不受OSGi的限制。OSGi中的最佳实践是编写普通旧Java对象,因此,OSGi服务不需要特殊的接口,甚至Java String对象也可以充当OSGi服务。这种策略使应用程序代码更容易移植到另一个环境。
嗯,这要看情况。Java最初的目标是在任何地方运行。显然,不可能在任何地方运行所有代码,因为Java vm的功能不同。移动电话中的VM可能不支持与运行银行应用程序的IBM大型机相同的库。有两个问题需要注意。首先,OSGi api不应该使用在所有环境中都不可用的类。其次,如果一个bundle包含在执行环境中不可用的代码,它就不应该启动。这两个问题在OSGi规范中都得到了解决。
来源:www.osgi.org/Technology/WhyOSGi
OSGi提供了以下好处:
■基于Java的可移植安全执行环境
■服务管理系统,可用于跨包注册和共享服务,并将服务提供者与服务消费者分离
轻量级和可扩展的解决方案
我还不是OSGi的“粉丝”…
我一直在财富100强公司使用企业应用程序。最近,我们使用的产品已经“升级”为OSGi实现。
启动本地cba部署… [2/18/14 8:47:23 727 EST] 00000347 CheckForOasis
最终部署,“以下bundle将被暂停,然后重新启动” [2/18/14 9:38:33 EST] 00000143 AriesApplicat I CWSAI0054I:作为应用程序更新操作的一部分
51分钟……每次代码改变…以前的版本(非osgi)在旧的开发机器上部署不到5分钟。
在一台有16g内存和40g空闲磁盘和Intel i5-3437U 1.9 GHz CPU的机器上
这次升级的“好处”被宣传为改进(生产)部署——我们每年大约做4次,每年可能有2-4个小的修复部署。每天给15个人(QA和开发人员)增加45分钟的工作时间是不合理的。在大型企业应用程序中,如果您的应用程序是核心应用程序,那么更改它就是核心应用程序,这是正确的(小的更改有可能产生深远的影响——必须与整个企业的消费者进行沟通和计划),这是一个重大的活动——不适合OSGi的架构。如果你的应用程序不是企业应用程序——也就是说,每个消费者都可以有自己的定制模块,可能会在自己的数据库中处理自己的数据筒仓,并在承载许多应用程序的服务器上运行,那么也许可以考虑OSGi。至少,这是我迄今为止的经验。
如果基于Java的应用程序需要添加或删除模块(扩展应用程序的基本功能),而不需要关闭JVM,则可以使用OSGI。通常,如果关闭JVM的成本比较高,那么仅仅是为了更新或增强功能。
例子:
请注意: Spring框架停止支持OSGI Spring bundle,认为它对于基于事务的应用程序或这些行中的某些点来说是不必要的复杂性。我个人是不会考虑OSGI的,除非绝对必要,比如在构建平台这样的大项目中。
其他人已经详细概述了OSGi的好处,我在此解释我所见过或使用过的实际用例。
OSGi会让你的代码莫名其妙地抛出NoClassDefFoundError和ClassNotFoundException(很可能是因为你忘了在OSGi配置文件中导出一个包);因为它有类加载器,它可以使你的类com.example.Foo不能转换为com.example.Foo,因为它实际上是由两个不同的类加载器加载的两个不同的类。它可以在安装Eclipse插件后将Eclipse引导到OSGi控制台。
NoClassDefFoundError
ClassNotFoundException
com.example.Foo
对我来说,OSGi只是增加了复杂性(因为它为我增加了一个心理模型),因为异常而增加了烦恼;我从未真正需要它“提供”的活力。它是侵入式的,因为它需要为所有模块配置OSGi包;这绝对不简单(在一个更大的项目中)。
因为我的糟糕经历,我倾向于远离那个怪物,非常感谢。我宁愿忍受jar依赖的地狱,因为这比OSGi引入的类加载器地狱更容易理解。
在它的官方网站上已经有了一个很有说服力的声明,我可以引用
OSGi技术如此成功的关键原因是它提供了一个非常成熟的组件系统,实际上可以在数量惊人的环境中工作。OSGi组件系统实际上用于构建高度复杂的应用程序,如ide (Eclipse)、应用服务器(GlassFish、IBM Websphere、Oracle/BEA Weblogic、Jonas、JBoss)、应用程序框架(Spring、Guice)、工业自动化、住宅网关、电话等等。
至于开发商的利益?
开发人员:OSGi通过为当今大规模分布式系统和小型嵌入式应用程序提供模块化体系结构来降低复杂性。从内部和现成的模块构建系统可以显著降低复杂性,从而降低开发和维护费用。OSGi编程模型实现了基于组件的系统的承诺。
请查看使用OSGi的好处中的详细信息。
我使用OSGi已经有8年左右的时间了,我不得不说,只有当你有业务需要在运行时更新、删除、安装或替换某个组件时,你才应该考虑使用OSGi。这也意味着您应该有一个模块化的心态,并理解模块化的含义。有一些争论说OSGi是轻量级的——是的,这是真的,但也有一些其他的框架是轻量级的,更容易维护和开发。同样的道理也适用于安全java等等。
OSGi需要一个可靠的体系结构才能正确使用,而且在没有任何OSGi参与的情况下,很容易使OSGi系统成为一个独立可运行的jar。