OSGi 的核心配置、动态化及问题
在改造这个基础产品时,我看到的使用OSGi的问题是:
1. 对没有接触过OSGi的Java开发而言开发习惯绝对是巨大的挑战
通常都会使用Maven来管理Java工程,肯定很希望mvn eclipse:clean eclipse:eclipse就可以生成导进eclipse里没问题的project吧,但对于OSGi而言,如果是依赖外部的非OSGi Bundle的jar,那么则需要在META-INF/MANIFEST.MF里写明,也就是不是仅仅修改pom.xml就可以的;另外一点是OSGi对于其他bundle的jar的依赖,不是通过pom.xml去增加依赖,而是直接import package或require-bundle之类的,并且要求这个bundle是已经安装了的(可以想象,如果是业务型的应用,那得装多少bundle…),否则在eclipse之类的ide里再去import什么的时候会找不到,同时为了确保mvn clean package之类的还是能用,因此会被逼在开发的时候要同时维护pom、MANIFEST.MF。
上面的这两个问题要解决好,可以通过开发IDE插件,但这个插件是不太好做的…
而OSGi的classloader机制则会给初入门的带来很多疑惑,会觉得经常碰到各种各样的class找不到等问题。
测试也是个麻烦,因为得把所有的bundle都装进framework,否则单元测试就得全部靠mock了。
另外一点在文件的依赖上就更折腾了,OSGi只能是通过require-bundle来去获取需要依赖的文件,否则是做不了的。
2. 动态化
OSGi确实具备了很强的动态化机制,但这里的要求是必须对OSGi bundle/OSGi Declarative Services的生命周期管理机制非常清楚,否则设计出来的系统其实是完全不可动态化的,具体的细节大家可以看看我之前写的另外一篇文章。
而仅仅借助OSGi的动态化机制,其实是不足以实现真正的热部署的,这里的一个原因是通常代码里是带状态信息的,或者说一些全局变量信息,而OSGi的替换其实主要是通过创建新对象实例,然后替换引用的方式来实现,这也就意味着对于有状态信息的,得自己处理好状态的保存以及还原,否则是会有问题的,我们当年为了在通信层面做到这点,折腾了一个多月还是没搞定,而且系统变得超级复杂。
另外还有个更麻烦的是,如果应用是OSGi和非OSGi混用,又要做动态化,那就得让非OSGi拿到的只是一个OSGi里对象的一个假的引用,以便随时替换,这个改造起来就更麻烦了。
当年那个基础产品改造完后,确实享受到了和应用隔离带来的好处,动态化在生产环境也玩过下,确实挺爽,但付出的代价是极大的,并且要做到真正的完全动态是不行的,也就意味着动态化这特性基本就是个玩具,因此后来在回顾这次技术决定时,我一直都承认,这是我做的一个最技术的,最失败的决定,如果是可以重来,我会选择不用OSGi,而是自己做一个简单的classloader隔离机制。
所以在那之后,当其他人问我是否可以在一些场景选择OSGi时,我给的建议都是:
如果你的场景不是对动态化(并且是无状态的那种动态化)有强烈的需求,那不要选OSGi。
仅仅是为了模块化,隔离这些,还不如自己做一个简单的实现,并且可以遵守现在的开发习惯,不要去挑战众多人的开发习惯和通用的知识体系,那对系统维护来说绝对会是一个灾难,只能说或许等到将来Java从语言级支持了可能才OK。
至于为什么众多的AS(例如Weblogic、JBoss)这些会选择基于OSGi,我觉得有一点很重要的是在没有选OSGi之前,他们对外提供的(销售的)版本是打包性质的,不能由用户来选择,这显然对销售会有限制,而如果能提供插件样的选择,则是一件好事,另外一个选择的原因很有可能是他们认为OSGi会成为语言级的标准,那意义就比较大了,不过可惜从目前来看,这估计不太可能。
至于众多人爱的eclipse,为什么选用OSGi,很大程度是看中了OSGi的动态化,以及减少了自己制定一个插件标准的折腾,eclipse这类插件的场景相对是比较好发挥动态化的(因为插件之间的交互依赖通常不多),尤其是在新装/停止一个插件时,更新会比较麻烦一些。
osgi最明显的缺陷
- bundle尽管可以为隔离的服务建立独立生命周期管理的热部署方式,以及明确的服务导出和导入依赖能力,但是其最终基于jvm,无法对bundle对应的服务实现计算资源的隔离,一个服务的故障依然会导致整个jvm crush,这使得在一个运行时的osgi上部署模块级服务只获得了模块部署和启停隔离,服务明确依赖的好处,但是没办法实现计算节点的线性扩展,在当前分布式,微服务,网络计算的趋势下,使得osgi只适合构建单一服务节点的内部应用,但是其分离的bundle的部署负担对于微服务架构来说,有点用大炮打蚊子的臭味。
推荐的应用架构方式
- 因此必须将基于进程间构建的分布式应用和进程内的单一应用分开来架构设计,对于进程间构建的分布式应用,采取基于soa的理念进行容器模式的服务部署模式,服务交互基于远程服务交互相关协议,采用可忍受网络失败的架构设计原则;
- 对于进程内的应用,如果需要模块级的独立生命周期热部署和模块管理,可以考虑采用OSGI,但是,容器内基于本地进程间通信的模块交付方式不仅能提供同样的独立生命热部署和模块管理,而且具备随时脱离出去部署成单独容器级服务应用的能力,加速进程间的服务交付提供的整体管理和监视环境基础.
- osgi还有用武只地吗?当然我前述都是以构建分布式企业和面向互联网这类应用为前提来讨论的,对于嵌入式的jvm应用,比如著名的osgi案例宝马的车载系统,osgi依然是最好的原则,不过我怀疑基于andriod系统的机制构建类似应用,osgi的采用依然值得商榷。因此,osgi确实面临鸡肋之嫌。
分布式应用的关键技术点及解决思路汇总
- 为什么要分布
为得到吞吐量和可靠性及故障隔离的架构属性,需要将传统的单一应用按照业务逻辑进行垂直拆分以实现构建工程的独立,部署的独立。 - 分布失去了什么
- 进程内服务调用的便利性和可测试性
- 代价巨大的资源分布导致的跨资源事务能力
- 部署和运维工作量指数级增长
- 不可靠网络的应用状态一致性
- 及其复杂的分布式应用依赖关系
- 分布式关键技术选择
- 容器级的分布式应用工程和部署管理;
- 可视化的分布式应用及服务监视管理视图;
- 前端和后端应用的分离;
- 客户端路由
- 服务注册中心
- 分布式协调
- 消息中件间
- 分布式存储
- 集成框架
OSGi 的核心配置、动态化及问题的更多相关文章
- PHP的核心配置详解
1.PHP核心配置详解 代码在不同的环境下执行的结果也会大有不同,可能就因为一个配置问题,导致一个非常高危的漏洞能够利用:也可能你已经找到的一个漏洞就因为你的配置问题,导致你鼓捣很久都无法构造成功的漏 ...
- kafka系列七、kafka核心配置
一.producer核心配置 1.acks :发送应答(默认值:1) 生产者在考虑完成请求之前要求leader收到的确认的数量.这控制了发送的记录的持久性.允许以下设置: acks=0:设置为0,则生 ...
- dubbo系列五、dubbo核心配置
一.配置文件 1.生产者配置provider.xml <?xml version="1.0" encoding="UTF-8"?> <bean ...
- 006-spring cloud gateway-GatewayAutoConfiguration核心配置-GatewayProperties初始化加载、Route初始化加载
一.GatewayProperties 1.1.在GatewayAutoConfiguration中加载 在Spring-Cloud-Gateway初始化时,同时GatewayAutoConfigur ...
- hibernate核心配置
# hibernate核心配置 注意: - hibernate.cfg.xml默认放在src目录下(这样可以自动加载该文件) - 必须配置的参数: * 数据库的四大参数和方言 - 可选配置的参 ...
- JavaWeb框架_Struts2_(二)----->Struts2的核心配置
2. Struts2的核心配置 2.1 配置Struts.xml文件 2.1.1 Struts.xml文件 Struts2框架的核心配置文件是Struts.xml,该文件主要用来配置Action和 ...
- Hibernate的核心配置
Hibernate的设计思路 Hibernate是一种全自动化管理持久化对象的ORM框架,既提供了完全面向对象的封装完整的对象持久化接口(屏蔽db层的差异化,提升代码可移植性),也提供了操作HQL和S ...
- MyBatis 核心配置综述之Executor
目录 MyBatis四大组件之 Executor执行器 Executor的继承结构 Executor创建过程以及源码分析 Executor接口的主要方法 Executor 的现实抽象 上一篇我们对Sq ...
- Atlassian In Action-Jira之核心配置(二)
道生一,一生二,二生三,三生万物. --<道德经> 如果说第一节的指导思想是管理之"道",那我们本节的核心配置就是Jira系统之"道"了.有了核心配 ...
随机推荐
- (转)Android学习笔记---SQLite介绍,以及使用Sqlite,进行数据库的创建,完成数据添删改查的理解
原文:http://blog.csdn.net/lidew521/article/details/8655229 1.SQLite介绍:最大特点是,无数据类型;除了可以使用文件或SharedPrefe ...
- hdu 2076
ps:WA了三次...第一次头脑有点乱,很麻烦的分几种情况讨论,第二次发现,只要分别算出时针和分针的角度,然后一减就行,却忽略了哪个大的问题,第三次加上了绝对值,就好了..就是以后double型比较最 ...
- 利用烧鹅制作简单BadUSB,插谁谁怀孕
所用硬件设备为烧鹅,烧鹅是RadioWar基于Teensy++ 2.0 AT90USB1286芯片设计的USB Rubber Ducky类开发板. 使用veil编码meterpreter生成paylo ...
- BZOJ 1042 硬币购物
先不考虑限制,那么有dp[i]表示i元钱的方案数. 然后考虑限制,发现可以容斥. 其实整个题就是两个容斥原理.感觉出的蛮好的. #include<iostream> #include< ...
- HDU 1109
http://acm.hdu.edu.cn/showproblem.php?pid=1109 一个范围内给一堆点,求到这些点的最短距离最大 模拟退火,温度是步长 #include <iostre ...
- iOS-NSURLCache内存缓存
在IOS应用程序开发中,为了减少与服务端的交互次数,加快用户的响应速度,一般都会在IOS设备中加一个缓存的机制.使用缓存的目的是为了使用的应用程序能更快速的响应用户输入,是程序高效的运行.有时候我们需 ...
- Python CSV模块处理文件读写
下面是一个简单的csv文件 Title,Release Date,Director And Now For Something Completely Different,1971,Ian MacNau ...
- 使用 CUBLAS 库给矩阵运算提速
前言 编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时.那么有没有一些现成的 CUDA 库来调用呢? 答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库. 本文将 ...
- Linux上的free命令学习
Linux新手,今天使用了free命令来查看电脑内存的使用情况.如下:-m表示以M来显示. 1.基本信息介绍 (1)其中纵向信息: Mem:表示物理内存大小 -/+ buffers/cached:表示 ...
- ZOJ Problem Set - 3640 Help Me Escape
题目大意: 有n条路,选每条路的概率相等,初始能力值为f,每条路通过的难度值为ci,当能力值大于某条路A的难度值b时,能够成功逃离,花费时间ti,小于等于时,不能逃离,天数加一天,但能力值增加b. 给 ...