聊聊OSGI

聊聊OSGI

当初看深入理解Java虚拟机的时候,对于osgi的部分就只是简单的略过,毕竟很少使用,也很少有人提起,感觉就是一个活在书本上的东西。不过最近。新公司的项目有用到osgi,所以还是得学习一下

原理

1. 模块

OSGI是一个基于Java语言的动态模块化规范。OSGI中的模块称为bundle,以jar格式封装,和普通的jar包区别不大,但是bundle可以通过Import-package声明对其他bundle的依赖,也可用通过Export-Package声明对外提供的服(在MANIFEST.MF文件中配置),这样就可以精确的控制bundle内部服务的可见性。

OSGI的模块化和平级依赖,使得OSGI的程序基本上可以实现bundle的热插拔,一个bundle的停用,只会影响到依赖该bundle的bundle,如果一个bundle不依赖任何其他的bundle,那么停用,升级部署的影响基本可以忽略。

2. 类加载

OSGi为每个bundle提供一个类加载器,OSGI的类加载顺序不同于双亲委派模式的向上委托,而是根据MANIFEST.MF文件的配置,去寻找类对应的加载器,类的加载可以在bundle间互相委托。所以OSGI的类加载器结构是平级的网状结构。

  • 步骤
    • 检查是否java.*,或者在bootdelegation中定义。如果是,则bundle类加载器立即委托给父类加载器(通常是Application类加载器)
    • 检查是否在Import-Package中声明。如果是,则找到导出包的bundle,将类加载请求委托给该bundle的类加载器。如此往复
    • 检查是否在Require-Bundle中声明。如果是,则将类加载请求委托给required bundle的类加载器
    • 搜索bundle的内嵌jar的类路径(Bundle Class Path)。如果找不到类或资源,继续下一步。
    • 查找Bundle的Fragment Bundle中导入的包, 如果没找到继续下一步
    • 如果类或资源位于自己导出的包中,则搜索结束并失败。
    • 否则,如果类或资源位于DynamicImport-Package导入的包中,则尝试动态导入包。
    • 如果动态导入包成功,则将请求委托给导出这个包的类加载器。如果请求被委托给导出类加载器并且找不到类或资源,则搜索终止且失败
特点

1. 特点

  • OSGi的入门门槛在Java众多技术中算是比较高的
  • OSGi本身就具有较高的复杂度
  • OSGi确实会增加系统不稳定的风险

​ bundle尽管可以为隔离的服务建立独立生命周期管理的热部署方式,以及明确的服务导出和导入依赖能力,但是其最终基于jvm,无法对bundle对应的服务实现计算资源的隔离,一个服务的故障依然会导致整个jvm crush,这使得在一个运行时的osgi上部署模块级服务只获得了模块部署和启停隔离,

​ 服务明确依赖的好处,但是没办法实现计算节点的线性扩展,在当前分布式,微服务,网络计算的趋势下,使得osgi只适合构建单一服务节点的内部应用,但是其分离的bundle的部署负担对于微服务架构来说,有点用大炮打蚊子的臭味

目前我的理解就是,一个庞大单体应用,需要分团队开发,用户量不多,需要分布式部署,但是又不需要像微服务架构一样,按服务拆分得那么细,那么就可以使用OSGI架构。


posted on 2020-05-31 13:42  灰马非马  阅读(1225)  评论(0编辑  收藏  举报

导航