JarsLink 是一个模块化的开发框架。由阿里巴巴开源出来,目前在阿里微贷事业群广泛使用。
JarsLink 原名Titan,它提供在运行时动态加载模块(一个JAR包)、卸载模块和模块间调用的API。官网地址:https://github.com/alibaba/jarslink。
JarsLink 模块化开发的好处
- 可插拔,一个应用由多个模块组成,应用里的模块可拆和合,模块可快速在多个系统中迁移和部署。
- 模块化开发,模块之间互相隔离,实现故障隔离。
- 一个模块一个分支,不会引发代码冲突。
- 在模块中增加或修改功能,只会影响当前模块,不会影响整个应用。
- 动态部署,在运行时把模块部署到应用中,快速修复故障,提高发布效率。
- 多版本部署,可以在运行时同时部署某个模块的新旧版本,进行AB TEST。
- 减少资源消耗,通过部署模块的方式减少应用数量和机器数量。
JarsLink 的使用
在 maven 的 pom.xml 中配置 JarsLink 的包。
<properties> <slf4j.version>1.7.7</slf4j.version> <apache.commons.lang.version>2.6</apache.commons.lang.version> <apache.commons.collections.version>3.2.1</apache.commons.collections.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${org.springframework.version}</version> <optional>true</optional> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>${apache.commons.lang.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>${apache.commons.collections.version}</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>17.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>com.alipay.jarslink</groupId> <artifactId>jarslink-api</artifactId> <version>1.5.0.20180213</version> </dependency> </dependencies>
在系统中配置 jarslink bean。
<bean name="moduleLoader" class="com.alipay.jarslink.api.impl.ModuleLoaderImpl"></bean> <bean name="moduleManager" class="com.alipay.jarslink.api.impl.ModuleManagerImpl"></bean>
接下来,我们集成JarsLink API。使用JarsLink API非常简单,只需要继承AbstractModuleRefreshScheduler,并提供模块的配置信息,代码如下:
public class ModuleRefreshSchedulerImpl extends AbstractModuleRefreshScheduler { @Override public List < ModuleConfig > queryModuleConfigs() { return ImmutableList.of(ModuleManagerTest.buildModuleConfig()); } public static ModuleConfig buildModuleConfig() { URL demoModule = Thread.currentThread().getContextClassLoader().getResource("META-INF/spring/demo-1.0.0.jar"); ModuleConfig moduleConfig = new ModuleConfig(); moduleConfig.setName("demo"); moduleConfig.setEnabled(true); moduleConfig.setVersion("1.0.0.20170621"); moduleConfig.setProperties(ImmutableMap.of("svnPath", new Object())); moduleConfig.setModuleUrl(ImmutableList.of(demoModule)); return moduleConfig; } }
这个调度器在bean初始化的时候会启动一个调度任务,每分钟刷新一次模块,如果模块的版本号发生变更则会更新模块。实现这个方法时,必须把模块(jar包)下载到机器本地,模块的配置信息说明如下:
- name:全局唯一,建议使用英文,忽略大小写。
- enabled:当前模块是否可用,默认可用,卸载模块时可以设置成false。
- version:模块的版本,如果版本号和之前加载的不一致,框架则会重新加载模块。
- Properties:spring属性配置文件。
- moduleUrl:模块的本地存放地址。
- overridePackages:需要突破双亲委派的包名,一般不推荐使用,范围越小越好,如com.alipay.XX。
把ModuleRefreshSchedulerImpl类注册成Spring的bean。
<bean id="moduleRefreshScheduler" class="com.alipay.**.ModuleRefreshSchedulerImpl"> <property name="moduleManager" ref="moduleManager" /> <property name="moduleLoader" ref="moduleLoader" /> </bean>
JarsLink API 暂时不提供模块可视化管理能力,所以需要使用其他系统来管理和发布模块。
目前可以通过com.alipay. jarslink.api.ModuleManager#getModules获取运行时所有模块的信息。
你也可以使用API来加载并注册模块,详细使用方式可以参考ModuleManagerTest,代码如下。
//1:加载模块 Module module = moduleLoader.load(buildModuleConfig()); //2:注册模块 ModuleManager moduleManager = new ModuleManagerImpl(); moduleManager.register(module);
在模块中只需要实现并开发Action,代码如下:
public class HelloWorldAction implements Action < ModuleConfig, ModuleConfig > { @Override public ModuleConfig execute(ModuleConfig actionRequest) { ModuleConfig moduleConfig = new ModuleConfig(); moduleConfig.setName(actionRequest.getName()); moduleConfig.setEnabled(actionRequest.getEnabled()); moduleConfig.setVersion(actionRequest.getVersion()); moduleConfig.setModuleUrl(actionRequest.getModuleUrl()); moduleConfig.setProperties(actionRequest.getProperties()); moduleConfig.setOverridePackages(actionRequest.getOverridePackages()); return moduleConfig; } @Override public String getActionName() { return "helloworld"; } }
开发者需要利用JarsLink API把请求转发给模块,先根据模块名查找模块,再根据aciton name查找Action,最后执行Action。
//查找模块 Module findModule = moduleManager.find(module.getName()); Assert.assertNotNull(findModule); //查找和执行 ActionString actionName = "helloworld"; ModuleConfig moduleConfig = new ModuleConfig(); moduleConfig.setName("h"); moduleConfig.setEnabled(true); ModuleConfig result = findModule.doAction(actionName, moduleConfig);
JarsLink 目前还有很多其他优秀的特性。网上的资料还是非常少的,关于深入的学习和使用,请参考官方文档。
: » 阿里巴巴 JarsLink 教程
原创文章,作者:bd101bd101,如若转载,请注明出处:https://blog.ytso.com/tech/java/251725.html