`
killko
  • 浏览: 104034 次
  • 性别: Icon_minigender_1
  • 来自: 广州
博客专栏
Group-logo
Servicemix&Fu...
浏览量:0
社区版块
存档分类
最新评论

我的OSGI学习历程

阅读更多
       系统开发到了一定程度的时候,我发现以往有很多可以再优化的地方,于是试图去优化,最终虽然优化了,但是因为牵连的东西有点多,所以花了不少时间。经过一番思考,才意识到需要优化的不是那些代码,而是那些架构。我们需要的大系统应该由多个相对独立的小系统组成,将业务分而治之。于是就去找合适的方法来达到这个目的,很幸运的是,我发现了OSGI。

       刚开始, 就只是知道 OSGI是一个实现模块化的架构,而且最初是作为一个嵌入式的java应用架构规范发展起来的,网上传得最有名的就是在BMW上的车载系统和Eclipse IDE这个两个应用。BMW没钱买来了解,只好看看Eclipse吧 

       想当年,我也尝试用eclipse来开发java程序,但嫌eclipse用起来太繁杂,用了几天,就没兴趣了,就转用比较简单,容易上手的Netbeans来做开发的IDE(也正是为了和其他习惯用eclipse的同事能合作好点,所以也就用上Maven,这是题外话了)。回过头来看Eclipse,依然是感觉超多的Plugins,弄的眼花缭乱。以前一直觉得Eclipse本身的开发也太复杂了吧,这么多的功能,得要多强大的全局观念才能兼顾得过来呀。知道有OSGI这回事后,才理解到,原来Eclipse并不需要多强的全局观念,它的功能都被“分而治之”了,这不正是我们的系统所追求的架构吗?于是,豁然开朗,但是这么多的令人眼花缭乱的功能还是令我静不下心来了解eclipse。

      于是,继续找,后来在apache上找到了felix,感觉挺清爽的,并且在felix.apache.org上了解到了很多OSGI方面的一些知识,再后来就看到了karaf,有了karaf,准备运行时环境就轻松了,于是就开始尝试去开发OSGI的bundle,然后放到karaf上跑。

      刚开始尝试做OSGI bundle,首先意识到的是如何组建一个bundle工程,想到既然一直以来都是用Maven做项目工程的,还是继续用Maven吧,再说OSGI Bundle在打包方面和JAR唯一的区别就是manifest.mf而已,而manifest.mf也是jar本来就有的东西,在OSGI bundle来说,只是内容上多加了几个小项而已。于是继续沿用原来的一套,拿个maven-jar-plugin插件在pom.xml里维护manifest项。

      接着就是尝试编码,直接写个BundleActivator的实现了,实现start和stop方法,只是往里面写个System.out.println Balabala...。mvn package生成一个bundle。扔到<karaf-root>/deploy文件夹下,运行<karaf-root>/bin/karaf.bat或<karaf-root>/bin/karaf.sh,console出现Balabala......。尝试着stop/start bundle,看着不断Balabala...。

     之后,就尝试一个bundle A在manifest.mf里export package,然后另一个bundle B在manifest.mf里import package,然后写代码用bundle A中的类创建个实例,并调用方法。扔karaf里运行之,还正常。尝试不同次序地stop/start这两个bundle,

     接着就尝试在Activator的start方法里,用BundleContext的registerService发布一个OSGI Service。也正常,在karaf console里用命令ls <bundle-id>,可以列出发布出来的服务。

    再接着尝试在另一个bundle里的Activator的start方法里,用BundleContext的getServiceReference方法引用刚才那个OSGI Service。也正常,可以引用并调用服务方法。

    So far so good!

   尝试不同次序地stop/start这两个bundle,问题出现了:服务引用那里会有返回null的情况,噩梦开始了。
  
   由于bundle启动的次序不确定,发布service的bundle可能会比引用service的bundle启动得晚。就会出现引用的服务为null。

   刚开始,我是通过在引用service的bundle的manifest里,添加import package来依赖发布service的bundle,这样当发布者未active时,引用者就不会resolved,所以,就曲线式决定了bundle的启动先后。但这是个坏实践。

  后来就采用ServiceListener或ServiceTracker的方式来引用服务,这样,服务就不再依赖bundle的启动次序了。但还有个致命的缺点----要写大量的代码。

  于是开始找DI的解决方案,刚开始选择了Declarative Service(DS),在felix项目下,有Service Component Runtime(SCR)的bundle可以支持Declarative Service,在manifest里用Service-Component项指定一个DS的XML文档,这个文档描述了服务及其组装关系。当bundle启动后,SCR bundle就读取该XML文档,解析并按文档组装起应用,如果某些服务未可用的话,就会延后到服务可用时再完成组装。这个过程完全由SCR bundle来管理。我们就不需要写ServiceListener或ServiceTracker来组装应用了,节省了大量的精力。

   再后来,又发现了更好的Blueprint的DI方案,于是就转向用Blueprint来取代Declarative Service,实现应用的组装。

  到此为止,系统还只是在单一个平台上运作,而我做的系统偏偏是由几个系统来组成的分布式的系统,于是继续找分布式的解决方案,于是又尝试ROSGI(这个开源项目已没有继续维护更新了)、接着CXF DOSGI,CXF DOSGI是可用,但发布的singlebundle版本太大(什么依赖都集成进去了),multiplebundle版本要剪裁,还存在一些和我自己用的某些bundle的版本冲突问题(这个也令我意识到import和export package时指定版本号及bundle版本管理的重要性,以后有空再聊聊这个问题)。所以cxf dosgi用了一段时间后,决定采用消息中间件来负责分布式系统间通讯的架构。

   在cxf dosgi里,osgi service可以跨framework地互相调用,但服务对应的API bundle就需要在关联的系统中各运行一个。采用消息中间件后,就不需要在不同的系统间共享API了,消息所在的队列、主题及消息本身的消息头,甚至消息体都隐式地定义了API,再加上消息的异步和同步的机制,使消息中间件的应用进一步增强了每个子系统的内聚,使子系统间的耦合更加松散。

   很“巧合”的是,Apache有个Servicemix的顶级开源项目,这个Servicemix和karaf的渊源十分深厚----karaf就是servicemix项目的内核独立分离出来的一个开源项目,所以,将所有以前开发的bundle移植到servicemix上,不费吹灰之力。Servicemix集成了ActiveMQ,于是Servicemix就成了我用来实现用消息中间件取代cxf dosgi方式的首选。

   上了Servicemix,自然就会用上了它集成的Camel,Camel强大的企业集成能力,将系统提升到面向服务的ESB层面了。

    既然上了SOA的贼船,就要想想将业务的规则和流程提炼出来,借助规则引擎或工作流引擎来实现,这是一条分支,暂时放下,日后再提。

    继续OSGI方面,在camel的支持下,无状态的服务纷纷被提炼出来,成为全系统通用的服务,而这些服务可以由众多细粒度的osgi服务来组装而成。服务采用消息处理器的方式实现,在对外的接口方面,则借助ESB来实现,要什么接口,就用什么Camel Component,这些Component都是现成的。至于消息路由,还是用那个用惯了的Blueprint吧:在Camel的命名空间(http://camel.apache.org/schema/blueprint)直接在CamelContext节点中定义消息路由。

    无状态的服务好解决,那么业务逻辑相关的有状态的部分怎么办呢?除了刚才提到的用规则引擎和工作流引擎外,Camel的消息处理器可以负责这部分的工作,具体的细节怎么做?我还要学习学习。

    讲了这么多,似乎还没有涉及到企业应用方面的东西,例如:持久化、事务(包括分布式事务)、Web等等。但还是暂时打住,分支太多了,这条裹脚(国脚)布也够长了。
5
0
分享到:
评论
9 楼 3gwind 2013-11-15  
楼主没有采用Eclipse 系 Equinox 的Virgo等的原因是什么 ,我最近才开始花时间学习OSGI,在选择上有些不解应该采用哪种方案,是Apache 还是 Eclipse。不知道楼主当时是如何选择的。
多谢
8 楼 buffering 2013-06-15  
学到东西了,希望楼主一直更新。
7 楼 baso4233 2013-04-16  
刚开始了解OSGi
6 楼 Kevin_jiang2011 2013-02-26  
菜鸟向楼主学习。
5 楼 killko 2013-02-21  
MrCrapBag 写道
能否放一些代码上来看看


http://killko.iteye.com/blog/1797364
4 楼 duduppp 2013-02-21  
搜到你这里来了,铜丝天涯沦落人
3 楼 killko 2013-02-21  
MrCrapBag 写道
楼主写的很好,最近正好也在看这个,一起学习一下

一起学习
2 楼 MrCrapBag 2013-02-19  
能否放一些代码上来看看
1 楼 MrCrapBag 2013-02-19  
楼主写的很好,最近正好也在看这个,一起学习一下

相关推荐

    OSGI实战

    - **7.1 关于OSGI**: 对OSGI的整体介绍和发展历程。 - **7.2 OSGI R4规范** - **7.2.1 Core Framework**: 核心框架的基础概念和组成部分。 - **7.2.2 StartLevelService**: 控制Bundle启动级别的服务。 - **7.2.3...

    《Java应用架构设计-模块化模式与OSGi》书中源码,美国 Kirk著,张卫滨译

    这个例子可能涵盖了支付处理系统的发展历程,涉及到模块化的演变,以及如何使用OSGi来管理和部署各个组件。读者可以通过研究这个案例,学习如何在自己的项目中实现类似的模块化结构,并利用OSGi来增强系统的灵活性和...

    SOA系列:Eclipse应用技术

    #### Eclipse概述与发展历程 Eclipse作为一个开放源代码的、基于Java的可扩展开发平台,自诞生以来便备受瞩目。它最初由IBM开发,2001年正式发布为开源项目。Eclipse不仅是一个简单的开发环境,更是一个强大的框架...

    eclipse从入门到到精通

    Eclipse 的发展历程见证了其从默默无闻到广受欢迎的转变,这得益于其不断进化的特性和开放源码的策略,吸引了诸如 IBM、Borland、Oracle 等大公司的参与。 **Eclipse 的体系结构** Eclipse 的核心设计理念是“一切...

    liferay入门经典(英文版)

    2. Liferay的架构:深入探讨Liferay的技术架构,包括它是如何利用各种Java技术和框架,如Spring、Hibernate、OSGi等来构建一个灵活、可扩展的平台。 3. Liferay开发环境搭建:书籍可能会提供关于如何搭建Liferay...

    视频播放器课程设计报告报告.pdf

    2. Java的发展历程包括JDK1.1至1.6(6.0)版本,其中1.2版本后分为J2SE、J2ME和J2EE,分别针对桌面应用、嵌入式应用和企业级应用。 3. J2SE是Java程序的基础环境,J2ME用于嵌入式设备,如手机,J2EE则服务于分布式...

    Eclipse与JDK完全手册

    RCP为富客户端应用程序提供了新的解决方案,通过OSGi(开放服务网关倡议)平台运行时实现了动态插件管理,解决了部署和维护的问题。3.x版本的关键特性包括: 1. 组件化:Eclipse插件模型允许应用由多个独立的组件...

    原创-java岗位技能与职业规划

    对于Java开发者,了解各个版本的J2SE(如JDK 1.1.x到J2SE 5.0)及其发布日期是非常重要的,这有助于理解语言的发展历程和不同版本间的特性差异。 在职业规划中,持续学习新技术和工具,提高在数据库管理、Web服务器...

    Java发展史_&_Java9、10新特性

    JShell是一个交互式的Java shell工具,允许开发者在命令行中即时编写和测试代码片段,这对于快速原型设计和学习非常有用。 通过回顾Java的发展历程以及详细介绍Java 9的新特性,我们可以看出Java语言一直在不断...

Global site tag (gtag.js) - Google Analytics