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