本文是蚂蚁金服微贷事业部自主研发的模块化开发框架TITAN的实现原理,该框架后续可能会开源,敬请期待!
1
需求背景
应用拆分的多或少都有问题。多则维护成本高,每次发布一堆应用。少则拆
分成本高,无用功能很难下线。
故障不隔离。当一个系统由多人同时参与开发时,修改A功能,可能会影响B功能,引发故障。
多分支开发引发冲突。多分支开发完之后合并会产生冲突。
牵一发动全身。一处核心代码的改动,或一个基础Jar的升级需要回归整个系统。
系统多,维护成本高。中间件升级每个应用都有升级成本。
2
模块化开发的好处
可插拔,一个应用由多个模块组成,应用里的模块可拆和合,模块可快速在多个系统中迁移和部署。
模块化开发,模块之间互相隔离,实现故障隔离。
一个模块一个分支,不会引发代码冲突。
在模块中增加或修改功能,只会影响当前模块,不会影响整个应用。
动态部署,在运行时把模块部署到应用中,快速修复故障,提高发布效率。
多版本部署,可以在运行时同时部署某个模块的新旧版本,进行AB TEST。
减少资源消耗,通过部署模块的方式减少应用数量和机器数量。
3
应用场景
模块化开发框架适用于一些易变的系统,需要经常在一个系统中开发需求,比如如下场景
数据采集,数据采集的数据源多,而且每种数据源都需要对接和开发,且数据质量很差,需要经常调整解析代码,通过模块化开发,实现一个数据源使用一个模块进行对接。
指标计算,每种消息一个模块,把消息转发到模块中进行消息处理。
后台管理系统,几乎每个系统都有后台开发的需求,新建应用则应用数多,维护成本高,引入模块化开发,一个二级域一个模块来开发后台功能。
业务核对系统,需要不停的在线上增加核对代码,每个系统一个核对模块。
4
实现原理
那么要实现模块化开发,需要实现几个功能,如何实现模块的加载和卸载,如何实现模块间的隔离和通讯,和模块的类加载机制。
模块的加载
TITAN为每个模块创建一个新的URLClassLoader来加载模块。并且支持突破双亲委派,设置了overridePackages的包将由子类加载进行加载,不优先使用父类加载器已加载的。
模块的卸载
卸载模块需要满足三个条件
模块里的实例对象没有被引用
模块里的Class没有被引用
类加载器没有被引用
所以需要做到三点卸载实例,卸载类和卸载类加载器,整个模块的卸载顺序如下:
关闭资源:关闭HTTP连接池或线程池。
关闭IOC容器:调用applicationContext.close()方法关闭IOC容器。
移除类加载器:去掉模块的引用。
卸载JVM租户(开发中):卸载该模块使用的JVM租户,释放资源。
模块间的隔离
模块化开发需要解决隔离性问题,否则各模块之间会互相影响。模块之间的隔离有三个层次:
类隔离:为每个模块创建一个类加载器来实现类隔离。
实例隔离:为每个模块创建一个新的IOC容器来加载模块里面的BEAN。
资源隔离:对每个模块只能使用指定的CPU和内存。
模块间通讯
模块之间的通讯也有三种方式,RPC,本地调用,深克隆/反射。
本地调用:目前TITAN的请求转发就是使用的这种通讯方式,这种方式要求通讯的两个模块都在一个JVM里,两个模块的类加载器是父子关系,并且两个模块的IOC容器也是父子容器。
RPC调用:用于跨JVM的模块之间调用,可以在D模块中发布服务,C模块引用RPC服务。
深克隆/反射:深克隆其他模块的入参,反射其他模块的方法实现调用,要求两个模块在一个JVM下。
类加载机制
OSGI类加载机制的关系采用的是网状结构,每个模块通过 Export-Package
来声明我要给别人用哪些类,通过 Import-Package
来声明我要用别人的哪些类。而TITAN框架采用的是扁平化管理,每个模块都有一个共同的父类,这个父类加载器就是加载ModuleLoader类的加载器,好处是便于维护,每个模块的类做到充分隔离,缺点是会加载重复的Class,适用于模块较少的场景。
(全文完)
近期很多人都在说想学习hadoop大数据,马云也说了:“未来最大的资源就是数据,不参与大数据十年后一定会后悔!”
目前腾讯的社交数据,百度的搜索数据以及阿里的交易数据每天都是PB级别,都是公司最重要的资产。
鉴于此,推荐一位非常牛逼的hadoop技术牛人:百度hadoop核心架构师,大数据团队Leader,曾获得百度技术最佳个人奖,百度职级T7,马上升T8 (百度大部分技术都是在T5,越往上越难升,在百度待3年能给到T5) 。
他现在在做大数据培训,对大数据开发感兴趣的可以加他助理咨询,扫一扫下面的二维码添加,注明来自:ifeve。可以获得他们的内部教材,以及3980元的VIP视频,先到先得!