Java隔离容器之sofa-ark使⽤说明及源码解析
⼀.使⽤⽅法及⽰例
简介:当引⼊⼆⽅依赖包或三⽅依赖包时,可能出现外部依赖jar包与⾃⼰的⼯程需要依赖的冲突,或者多个⼆⽅三⽅依赖包互相冲突。这时候就需要⼀个隔离容器对他们进⾏隔离,其依赖的原理就是jvm认为不同classloader加载的类即使包名类名相同,也认为他们是不同的。sofa-ark将需要隔离的jar包打成plugin,对每个plugin都⽤独⽴的classloader去加载。
(温馨提⽰:若对sofa-ark不太了解的,最好先去看看,简单了解下)
使⽤的基本步骤:
1. 在会发⽣冲突的jar包的POM⽂件加⼊sofa-ark提供的maven插件,将其打成特定格式的jar包(plugin)。
2. 在外部⼯程按照约定引⼊jar包。如果外部⼯程想打包成可执⾏的jar(fat-jar),还需要加⼊特定的maven插件。
3. 直接运⾏。
名词解释:
Ark Container: Ark 容器,是组件 SOFAArk 的核⼼,运⾏ Ark 包时,Ark 容器会最先启动,负责应⽤运⾏时的管理,主要包括构建Ark Plugin 和 Ark Biz 的类导⼊导出关系表、启动并初始化 Ark Plugin 和 Ark Biz、管理 Ark Plugin 服务的发布和引⽤等等。
Biz:即业务⼯程,该⼯程引⽤⼀个或多个外部jar包。
plugin:会发⽣冲突的外部依赖jar包经过提供的Maven插件打成的fat-jar包。运⾏时,由独⽴的类加载器加载,因此有隔离需求的Jar 包建议打包成 Ark Plugin 供应⽤依赖。
1.0 sofa-ark原理
在sofa-ark中,使⽤container容器启动外部⼯程(Biz)和冲突jar包(plugin),sofa-ark的plugin maven插件将冲突的jar包打包成为plugin,外部⼯程只能引⽤plugin exported出来的类,并且这个类是由独⽴的PluginClassLoader加载的,从⽽解决了jar包冲突的问题。
1.1 冲突⽰例
1.2 安装sofa-ark
java xml是什么从 将整个⼯程下载下来,在最外层l所在路径执⾏mvn package和mvn install 将sofa-ark依赖jar包安装到本地。
1.3 创建基础依赖Jar包(冲突的包)
⾃⼰创建myjar⼯程,先后正常打包两个版本安装到本地maven仓库。
如:v1版本
v2版本
1.4 创建service包(plugin)
创建如图所⽰两个⼯程:
在myJarservice-v1和myJarservice-v2的pom中分别引⽤之前写的两个基础依赖jar包。然后在MyJarService1和MyJarService2中分别引⽤对应版本的myjar包⾥的⽅法。
如MyJarService1.java:
MyJarService2.java
注意:这⾥两个Service引⽤的是不同版本的myjar。
接下来需要对两个⼯程打包,和平常打包不⼀样的是需要加⼊sofa-ark-plugin的maven插件。两个⼯程下的l都要加⼊:
<build>
<plugins>
<plugin>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-plugin-maven-plugin</artifactId>
<version>0.4.0-SNAPSHOT</version>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>ark-plugin</goal>
</goals>
<configuration>
<!-- configure exported class -->
<exported>
<!-- configure class-level exported class -->
<classes>
<class>comease.sofaservice.MyJar1Service</class>
</classes>
</exported>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
复制代码
在exported标签⾥写出要对外提供的⽅法,外部要引⽤的所有⽅法都必须写在这⾥,可以以类(<classes>)为单位和包(packages)为单位导出。
到parent⼯程路径下mvn package和mvn install 即可。
1.5 外部⼯程引⽤(Biz)
新建⼀个⼯程,在l引⼊以下依赖:
<dependencies>
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-support-starter</artifactId>
<version>0.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>comease</groupId>
<artifactId>myjarservice-v1</artifactId>
<classifier>ark-plugin</classifier>
<version>1.0</version>
</dependency>
<dependency>
<groupId>comease</groupId>
<artifactId>myjarservice-v2</artifactId>
<classifier>ark-plugin</classifier>
<version>1.0</version>
</dependency>
<dependency>
<groupId>comease</groupId>
<artifactId>myjarservice-v1</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>comease</groupId>
<artifactId>myjarservice-v2</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
复制代码
注意要添加<classifier>标签,因为IDE识别不了ark-plugin的jar包,所以需要再引⼊⼀个范围为provided的jar包。然后l还要添加maven插件:
<build>
<plugins>
<plugin>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-maven-plugin</artifactId>
<version>0.4.0-SNAPSHOT</version>
<executions>
<execution>
<id>default-cli</id>
<!--goal executed to generate executable-ark-jar -->
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<!--specify destination where executable-ark-jar will be saved, default saved to ${project.build.directory}-->
<outputDirectory>./</outputDirectory>
<!--default none-->
<arkClassifier>executable-ark</arkClassifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
复制代码
然后再随便写个类引⼊两个版本service包的类使⽤即可,在main函数⼊⼝处需要加上⼀句:
SofaArkBootstrap.launch(args);
可以看到打印结果:
⼆.sofa-ark-plugin-maven-plugin插件原理分析
2.1 查看plugin jar包内容
使⽤sofa-ark-plugin-maven-plugin Maven插件即可将jar包打包成可在container中隔离加载的jar包(如myjarservice-v1-1.0-ark-plugin.jarr和myjarservice-v2-1.0-ark-plugin.jar)。进⼊本地maven仓库myJarservice-v1⼯程所在位置,可以看到maven打了两个包:⼀个是maven⾃带的插件打的普通的包:myjarservice-v1-1.0.jar ,另⼀个是sofa-ark提供的maven插件打的包myjarservice-v1-1.0-ark-plugin.jar,打开myjarservice-v1-1.0-ark-plugin.jar 可以看到如下⽬录:
相关⽬录说明:
com/alipay/sofa/ark/plugin/mark :标记⽂件,标记该 Jar 包是 sofa-ark-plugin-maven-plugin 打包⽣成的 Ark Plugin ⽂件。
META-INF/MANIFEST.MF :记录插件元信息,其中包含要导出的和导⼊的类。
Manifest-Version: 1.0
groupId: comease
artifactId: myjarservice-v1
version: 1.0
priority: 100
pluginName: myjarservice-v1
activator:
import-packages:
import-classes:
import-resources:
export-packages:
export-classes: comease.sofaservice.MyJar1Service
export-resources:
复制代码
conf/export.index :插件导出类索引⽂件;为了避免在运⾏时计算MANIFEST.MF 中export-packages 下⾯具体的导出类,在打包⽣成 Ark Plugin 时,会⽣成插件所有导出类的索引⽂件,缩短 Ark Container 解析配置时间。
lib/ : lib ⽬录存放插件⼯程依赖的普通 Jar 包,⼀般包含插件需要和其他插件或者业务有隔离需求的 Jar 包;插件配置的导出类都包含在这些 Jar 包中。
2.2 分析sofa-ark-plugin-maven-plugin源码
进⼊下载的sofa-ark源码中的ark-plugin-maven-plugin⼯程,可以看到ArkPluginMojo继承了
@Mojo(name = "ark-plugin", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME)
public class ArkPluginMojo extends AbstractMojo {
@Parameter(defaultValue = "${project.artifactId}")
public String                  pluginName;
@Parameter(defaultValue = "100", property = "sofa.ark.plugin.priority")
protected Integer              priority;
@Parameter
protected String                activator;
@Parameter
protected ExportConfig          exported;
@Parameter
protected ImportConfig          imported;
...
复制代码
@Mojo 就是⼀个 goal,可以绑定到某个 phase (这⾥是package)执⾏,@Parameter 是从外⾯传进来的参数,可以直接获取xml中配置的参数。Maven插件标准要求必须重写execute()⽅法,插件执⾏时主要就是执⾏execute()。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。