Java Modular Programming--Three Concept Layers of OSGI

foreword

 

In a recent project, the hot update of the jar package needs to be implemented. The initial implementation method is to use a custom ClassLoader . But this way of customizing ClassLoader can only realize the hot loading of the jar package for the first time (that is, after the program starts, a new jar package is introduced into the jvm ), and there is no way to update the jar package version.

 

Specifically, why is there no way to achieve hot update of jar packages? Suppose now that the corresponding class files in jar 1.0 have been loaded into the JVM memory using a custom ClassLoader , and the corresponding versions of Class objects are generated, and these objects will be cached ( into the method area). At this time, if jar2.0 is updated, the new class file cannot be loaded into the JVM because the old version of the Class object (method area) already exists in the cache . Since there is no unloading method of class and classloader provided in JVM , it is a complicated process to implement it yourself.

 

This actually involves the modular programming of java . OSGI happens to be a relatively mature technical solution, and the famous Eclipse is based on OSGI to realize hot plugging of plug-ins ( after Eclipse 3.0 ). After the introduction of this technology, the problem we are facing has been solved very well. In addition , jdk1.9 also launched its own modular programming solution Jigsaw , but at present, jdk1.9 has not been commercialized on a large scale, and it has been excluded from technical selection.

 

There is still a certain cost of learning to use OSGI in existing projects. I am going to make some conclusions about the introduction process of OSGI . First start with some theoretical foundations.

 

The three conceptual layers of OSGI

 

OSGI specification and OSGi framework: The OSGI specification is a set of technical specifications formulated by the OSGI Alliance, which is essentially a series of interfaces; a simple understanding of the OSGI framework is the implementation of the interfaces defined in the OSGI specification by various software vendors. The three more famous ones are OSGI frameworks: Apache Felix , Eclipse Equinox , Knopflerfish . The relationship between the OSGI specification and the OSGi framework is somewhat similar to the jvm specification and the Hotspot virtual machine.

 

The three conceptual layers of OSGI should be precisely the three conceptual layers defined by the OSGI specification: module layer, life cycle layer, and service layer.

 

Module Layer: Each OSGI module is called a bundle , which is a jar file that contains metadata . The difference from ordinary jars is that there is a META-INF directory in the jar package corresponding to each bundle , which contains a MANIFEST.MF file (now most of the jar packages imported through Maven have this file), which is the "meta -inf" file. data". It can be easily understood that bundle= normal jar+MANIFEST.MF (metadata description file), so the MANIFEST.MF file is the core of boundle .

 

The MANIFEST.MF file can define which packages ( package ) are visible to the outside world ( export export). After this bundle is loaded in the OSGI container, other bundles import the required packages ( package ) through import , and use the classes in these packages.

 

这里有一个exportimport的概念,bundle之间的API相互依赖都可以通过exportimport相关的包(package)来完成。在一个bundle中只有export导出的api才能被其他bundle使用,即使是定义为publicapi如果没有被export导出,对于其它bundle来说是不可见的。这这个层面上讲,bundle扩展了java的访问修饰符:public、默认、privateprotected

 

简单的理解模块层,就是在jar包的基础上加元数据,也就是配置MANIFEST.MF文件,一个简单的MANIFEST.MF配置文件如下:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: gantianxing
Build-Jdk: 1.8.0_65
Bundle-Activator: com.sky.osgi.MtActivator
Bundle-ManifestVersion: 2
Bundle-SymbolicName: osgibundle222
Import-Package: com.sky.osgi.server

 

 

后面再抽时间单独对MANIFEST.MF文件的配置方法单独进行总结。

 

生命周期层:顾名思义,其主要作用是控制如何管理bundle的生命周期,比如bundle的在容器里的安装、更新、启动、停止、卸载,以及如何管理应用程序。这些API都是在生命周期层定义。在这一层,OSGI规范中定义了很多接口来实现对bundle的管理,后面再抽时间进行总结。

 

服务层:这层的概念有点类似SOA服务治理,与SOA服务治理一样 OSGI的服务层包含:服务注册中心、服务提供方、服务使用方(客户端)。与SOA服务不同的是,OSGI的服务层的注册中心、服务提供方、服务使用方都在一个jvm实例内部,而SOA的服务是分布式的。这也就是所谓的:OSGIJVM内部的SOA服务治理框架。

 



 

                    摘自《OSGI实战》

 

OSGI的工作流程如上图,可见其工作方式与普通RPC框架是类似的(比如Dubbo),这里只是在一个jvm实例中完成:首先服务提供者向注册中心发布服务,客户端要使用某个服务时首先到注册中心查找,如果找到对应的服务,就直接调用该服务(有点类似服务直连)。

 

另外OSGI服务的开发模式也跟普通的RPC服务类似,是一种基于接口的开发模式,实现与接口分离。在发布服务时,只需把接口类暴露出去(export),服务使用方导入这些接口类再通过注册中心查找即可。

 

注意这里使用服务与普通export的区别,使用服务:服务提供方只是往外暴露(export)了接口类,具体的实现类对客户端(另一个bundle)来说是不可见的;普通的export是导出整个具体的实现类,客户端导入后可以直接使用。简单理解就是,前者只是export接口隐藏实现,后者是直接export实现。

 

相对于直接export实现类来说,使用服务发布的方式有很多好处:服务端是一个bundle 具体的实现被封装到这个bundle中,客户端是其它bundle,当服务端有内容需要更新时,客户端是无感知的。就类似于普通的RPC框架里,服务提供方法有代码更新需要重新上线,而对服务使用方(客户端)来说是不需要同步上线的。这应该就是OSGI能实现热更新的根本原因:



 

如果上图bundle1-3是服务使用方,bundle4-6是服务提供方(当然也可以即使服务提供方,也是其它服务的使用方,最终可能是一个网状结构),比如:当服务提供方bundle4需要更新重新加载时,此时这个服务只是短时间不可用,其它bundle可以正常工作,只是bundle1在调用bundle4的服务时,发现服务不可用,这时可以进行异常处理或者进行轮询等待即可。

 

 

关于OSGI的三个概念层,本次总结只是简单的从理论概念上进行了描述,具体模块层元数据怎么配置?生命周期层如果管理?服务层如何注册和发现服务?对于这三个问题,后面再单独抽时间总结下。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326317356&siteId=291194637