Detailed explanation of OSGi modular framework

The OSGi modular framework is a plug-in framework that came out very early. Eclipse was first famous for using it, but it has not been popular in recent years. Although OSGi has released version 1 to version 5 . Now the most used, and this article is based on Equinox 's OSGi implementation, which is also the core of Eclipse, and the Spring Dynamic Module is also based on Equinox . The OSGi framework provides a general container for the java system. The bundles in the system can be installed and uninstalled without stopping the system. OSGi is currently the only modular, dynamic specification in Java. In terms of modularity, the OSGi Alliance has been researching for many years, so the OSGi specification has a very perfect mechanism for the physical isolation of modules, module interaction, and multiple versions, and has also been obtained by almost all App Server manufacturers or Recognized by the open source community, but has not been incorporated into the language level by JAVA (to be seen). The outstanding features of OSGi are:

  • Modules can be dynamically loaded, updated and unloaded without stopping the service
  • Realize the modularization and versioning of the system, allowing multiple versions of bundles to be served at the same time
  • Service model allows modules/plugins to be interdependent but loosely coupled, making it easier to share services

OSGi runs on the JVM, and its architecture is shown in the following figure:

osgi_framework

OSGi applicable scenarios

Many people use OSGi incorrectly , applying the OSGi architecture to complicate the system. In my opinion, the usefulness of OSGi is " modular " and " hot- pluggable ". Modularity includes modularity, versioning, and service-oriented design. Hot-plugging means hot-plugging of modules/bundles, which can update and upgrade modules/bundles (i.e. part of the system) without restarting the entire system.

If your system adopts the OSGi architecture, the interdependencies of bundles are complex, and there is no mechanism for dynamic loading, dynamic updating, dynamic unloading and dynamic monitoring of bundles, all bundles are started statically, that is, the OSGi architecture is for the OSGi architecture. The problem is complicated. The cost is also very high, because it is convenient for your jar package to use maven to handle dependencies and automatic updates, and because the entire system is built on the OSGi specification, other components that your application depends on "have to" migrate Coming to OSGI, coupled with OSGI's unique ClassLoader design, the mutual access of classes between bundles is subject to certain constraints, and everything needs to be migrated to the constraints of OSGi.

For example, just like Eclipse provides a mechanism to dynamically load, update and delete plug-ins, because it has a plug-in registration and anti-registration interface and plug-in loading, update and deletion listening threads, which allows you to dynamically load, update and delete plugins. Update and remove Eclipse plugins without restarting Eclipse. Of course, if your current process calls a plugin, such as js syntax highlighting, and a plugin is updated, the current js instance still needs to be reopened. But the whole Eclipse doesn't need to be restarted.

The difficulty of Java modularization

An important feature of OSGi is modularity. OSGi provides a modular system, in which there will be clear interface exposure and dependency definition between modules, so it can better achieve high cohesion and low coupling. So, what is the difficulty of Java modularization? There are indeed some differences between the implementation of modules and traditional programming methods, which are mainly reflected in the isolation of class access between modules and the selection of versions. If you want to better design a modular system, developers need to master the ClassLoader mechanism and the interaction method of classes between modules (this includes how modules provide accessible packages to the outside world, how to access packages provided by other modules, and how to choose appropriate version of the package, etc. ). If you don't understand the above, rashly applying the OSGi framework will go astray.

Important Concept: Bundle

Bundle — A bundle is a JAR file with special OSGi entries in its manifest and containing classes, resources, and other JARs. Bundle, which can be understood as a self-describing JAR file. Bundle is the smallest unit of deployment in OSGi, so it can be understood as a module. In the bundle's manifest file, there will be definitions of the bundle's identity, provided functions (Export-package) and dependencies (Import-Package/Require-Bundle). Each bundle has its own class loader (Class Loader) at runtime, which can distinguish the classes in different bundles on the one hand. When the bundle is unloaded, only the information in the class loader of this bundle will be Lost; on the other hand, you can take advantage of Java's member access control mechanism within your own bundle.

Bundles are self-describing via MANIFEST.MF, here is an example:

1
2
3
4
5
6
7
8
9
10
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Popup Plug-in
Bundle-SymbolicName: com.example.myosgi; singleton:= true
Bundle-Version: 1.0 . 0
Bundle-Activator: com.example.myosgi.Activator
Require-Bundle: org.eclipse.ui,
  org.eclipse.core.runtime
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE- 1.6

Bundle class isolation mechanism

Each Bundle is an independent ClassLoader, which is the basis for the dynamic implementation of java. By default, there are Boostrap classloader (jre/lib/classes), Extension classloader (jre/lib/ext), and System classloader (specified by classpath). Applications can implement classloader and dynamically load classes, or load classes in a specific directory.

 

Bundle life cycle

Lifecycle — A lifecycle is the sequence of states a bundle goes through: uninstalled, installed, resolved, starting, stopping, active. The lifecycle diagram is as follows:

osgi_lifecycle

要注意的是:bundle状态变为Resolved并不表示能提供服务,所以启动所有的bundle不表示类都已经加载到内存了。Resolve bundle做以下的几件事情:寻找bundle依赖的包是否存在以及被resolve,寻找匹配的import package,required bundle,如寻找则进入检查,检查没有冲突就形成绑定关系,以便加载类的时候能直接加载(但仅仅Resolved,不代表类被加载了)。如果你的BundleActivationPolicy是LAZY惰性加载,bundle.loadClass()调用才会到达Active状态。如果你的bundle的MANIFEST.MF中配置的Bundle-activator存在,那就调用其start方法,从starting进入active状态。

1
2
3
4
5
osgi> ss
   "Framework is launched."
   id      State       Bundle
   15       STARTING    com.example.serviceconsumer_1. 0.0 .X
   16       RESOLVED    com.example.serviceprovider_1. 0.0 .X

xds50.gif.pagespeed.ic.DzxMZ781Q5

下面的图更详细的解释了这一点:

OSGiBundleStateDiagram

 

OSGi Service

Service — A service is an object instance exposed under the one or more interfaces that it implements and a map of properties. 简单来说,Service model允许每个bundle对外分享一组服务,其它的bundle都可以调用这些接口的服务。这也就是OSGi bundle之间调用的方式。Service可以用来:

  • Export functionality from a bundle to other bundles
  • Import functionality from other bundles
  • Register listeners for events from other bundles
  • Expose external devices, such as UPnP devices or even hardware, to other OSGi bundles. See the Device and UPnP APIs
  • Expose java code running in OSGI to an external network, e.g. via the UPnP or SOAP protocols.
  • Bundle configuration, using the Configuration Manager

实际做法来看,通常会把接口和实现分开。接口放到一个bundle里面。实现(service)放到另外一个bundle里面,类似下面的图示中,bundle A和B是Service,其interface放到Bundle C:

dfhpj_osgiframework

也可以是提供一个jar包,里面定义了扩展接口,然后规定新的扩展bundle必须实现该jar包里面定义的interface。实现示意图如下所示(OsgiCommand接口定义在扩展点jar包里面,新的bundle必须包含):

2014-02-13_16h14_59

Bundle的Service之间交换方式和注册方式:

第二种通过ServiceTracker 来查询或侦听服务注册和注销的例子代码:

 

OSGi简单起步

从Eclipse创建OSGi的bundle是非常简单的,简单起步可以参考这几篇文章:<Creating a new OSGi Bundle using Eclispe>,以前这篇

Slideshare: OSGi理论与实战

OSGi动态加载删除bundle

分布式OSGi(Distributed OSGi)

OSGi容器可以包含几千个bundlue没有问题,但如何应对几十万个的情况?如何像EJB3一样具有分布式部署和便携性呢?有一个OSGi的子项目:分布式OSGi(Distributed OSGi)

dosgi_cxf

 

上图是一个demo演示,两个分布式OSGi Container,都部署了Greeter接口bundle,都基于分布式OSGi实现,能实现分布式调用OSGi Service。分布式OSGi(Distributed OSGi)还可以与RESTful Service (JAX-RS / JSR-339)整合。分布式OSGi有几十万个bundle怎么管理,这是个麻烦,而且如何启动停止,启动顺序怎么样?可管理性是个麻烦,ACE项目试图解决这个事情。

DOSGi的原理(由Distribution provider来给OSGi Service创建Endpoint,使这些Service在OSGi Container外部可访问,另外一端则创建代理;此外,有监听器来侦听OSGi Service的创建和启停等):

remote-services-spec

分布式OSGi与ZooKeeper

ZooKeeper是Hadoop的一个子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

分布式OSGi(Distributed OSGi)在Discovery这一块使用了ZooKeeper。所谓Discovery模块就是用来发现和侦听分布式的远端的可用的Endpoints。Discovery Ditributed with Zookeeper的架构图

cxf-dosgi-discovery-distributed

Reference: DOSGi uses ZooKeeper server installation and Demo .

Guess you like

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