-
Notifications
You must be signed in to change notification settings - Fork 513
-
Fully support SpringBoot With middleware
No due date Last updated about 1 year ago -
support SOFABoot 4.0 and SpringBoot 3.0
No due date Last updated over 1 year agoalready found diff: Execution default-cli of goal com.alipay.sofa:…
already found diff:
- Execution default-cli of goal com.alipay.sofa:sofa-ark-maven-plugin:2.2.1:repackage failed: Unsupported class file major version 61
- com.alipay.sofa.boot.skip-jvm-reference-health-check=true need change to sofa.boot.runtime.skip-jvm-reference-health-check=true
- we only had com.alipay.sofa.ark.springboot.listener.ArkApplicationStartListener#isSpringBoot1 and com.alipay.sofa.ark.springboot.listener.ArkApplicationStartListener#isSpringBoot2, but no support to springboot3
-
9月迭代
No due date Last updated over 1 year ago -
8 月份迭代
No due date Last updated over 1 year ago -
Static variable in multi classLoader
No due date Last updated over 1 year ago在基座与多模块模式下,基座和每个模块都是一个 ClassLoader,在多ClassLoader 下,如果存在静态变量共用的话,如果该…
在基座与多模块模式下,基座和每个模块都是一个 ClassLoader,在多ClassLoader 下,如果存在静态变量共用的话,如果该变量没有特殊设置成支持多 ClassLoader 则会出现变量覆盖的问题。例如 #672
private static ApplicationContext applicationContext = null;
该变量被多个模块覆盖,不同模块在使用的时候只能拿到最后一次的值,导致非预期问题。类似的问题还有其他依赖里有,这里做为记录跟踪。 -
enable Spring cloud dev framework
No due date Last updated over 1 year agocurrent, we didn't fully support springboot or springcloud, now we need to enable this.
-
Fully support SOFABoot With middleware
No due date Last updated over 1 year ago -
backlog
No due date Last updated over 1 year ago -
DeclaredMode: bizClassLoader delegate to Master ClassLoader only declared in biz module
Past due by over 1 year Last updated over 1 year ago类委托加载 注:这里委托加载不止包含类委托,还包含资源委托加载。 SOFAArk 通过多 ClassLoader 的方式提供类隔离的能…
类委托加载
注:这里委托加载不止包含类委托,还包含资源委托加载。
SOFAArk 通过多 ClassLoader 的方式提供类隔离的能力,并在此基础上具备多版本隔离和热部署的能力。当然类如果纯粹隔离还不够,还需要考虑ClassLoader之间的类共享。SOFAArk 通过类委托机制,提供了一套丰富的委托加载能力。定义了PluginClassLoader 和 BizClassLoader,不同类型具备不同的类查找逻辑,同时提供ClassLoaderHook能力,允许自定义模块间的类委托加载。SOFAArk 框架本身的类委托加载是非常灵活的,但是在实际落地时,需要有一套类委托加载的最佳实践。
SOFAArk 支持的场景主要分为两类:
- 多Plugin的类隔离:考虑如何相同类不同版本不会相互冲突
- 合并部署/热部署:原应用如何拆分,或多个应用如何合并
这里我们主要考虑第2种,多 ClassLoader 如何布局,在内部探索出的最佳实践多 ClassLoader 布局为
模块里的类和资源查找优先从模块里查找列,查找不到从再基座里查找。
最佳实践
类委托加载的准则是中间件相关的依赖需要放在同一个的 ClassLoader 里进行加载执行,达到这种方式的最佳实践有两种:强制委托加载
由于中间件相关的依赖一般需要在同一个ClassLoader里加载运行,所以可以制定一个中间件依赖的白名单,强制这些依赖委托给基座加载。SOFAArk 已经提供白名单能力,详细查看与
sofa.ark.plugin.export.class.enable
有关源码。强制加载优缺点
- 优点
模块开发者不需要感知哪些依赖属于需要强制加载由同一个 ClassLoader 加载的依赖
- 缺点
白名单里要强制加载的依赖列表需要维护,列表的缺失需要更新基座,较为重要的升级需要推所有的基座升级。
自定义委托加载
模块里pom通过设置依赖的 scope 为 provided主动指定哪些要委托给基座加载。通过模块瘦身工具自动把与基座重复的依赖委托给基座加载,基座通过预置中间件的依赖(可选,虽然模块暂时不会用到,但可以提前引入,以备后续模块需要引入的时候不需再发布基座即可引入)
1. 基座预置依赖
基座可以提前预置一些依赖
2. 通过两种方式委托给基座加载
- 模块pom里依赖 scope 设置为 provided
- biz 打包插件sofa-ark-maven-plugin里设置 excludeGroupIds 或 excludeArtifactIds
3. 只有模块声明过的依赖才可以委托给基座加载
模块启动的时候,框架会有一些扫描逻辑,这些扫描如果不做限制会查找到模块和基座的所有类、资源,导致一些模块明明不需要的功能尝试去初始化,从而报错。SOFAArk 2.0.3之后新增了模块的 declaredMode, 来限制只有模块里声明过的依赖才可以委托给基座加载。只需在模块的 sofa-ark-maven-plugin 打包插件的 Configurations 里增加 true即可。
自定义委托加载优缺点
- 优点
不需要维护强制加载列表,当部分需要由同一 ClassLoader 加载的依赖没有设置为统一加载时,可以修改模块就可以修复,不需要发布基座(除非基座确实依赖)。
- 缺点
对模块自动瘦身的依赖较强
对比与总结
依赖缺失排查成本 修复成本 模块改造成本 维护成本 强制加载 类转换失败或类查找失败,成本中 更新 plugin,发布基座,高 低 高 自定义委托加载 类转换失败或类查找失败,成本中 更新模块依赖,如果基座依赖不足,需要更新基座并发布,中 高 低 自定义委托加载 + 基座预置依赖 + 模块自动瘦身 类转换失败或类查找失败,成本中 更新模块依赖,设置为provided,低 低 低 推荐自定义委托加载方式
- 模块自定义委托加载 + 模块自动瘦身
- 模块开启 declaredMode
- 基座预置依赖
关于 declaredMode 的逻辑介绍:
模块打包插件,需要通过执行 mvn dependency:tree 获取模块的所有依赖列表
模块启动或运行时查找类和资源时,找到对应基座的jar,提取jar里的artifactId,跟打包时获取到的依赖进行对比,如果模块里有声明,则委托加载成功,如果模块里没声明,则委托加载失败。
这段逻辑有两个关键地方,一是模块打包扫描的依赖是否完整,而是从基座jar里提取 artifactId 是否正确,这两处如果有任何一处有疏漏都会出现你这种情况。这段逻辑当前是不够完善的,希望一起把它完善起来。开启后的副作用
- 由于基座提前启动,模块再次启动的时候,如果依赖了基座的依赖里有发布服务,那么模块在启动的时候还会再次发布,如果该问题有一定影响可以模块pom里exclude掉对应的依赖。
- 模块启动会出现
Unable to instantiate org.springframework.boot.env.EnvironmentPostProcessor
, 详见 #611 - 从基座里查找出来的依赖,需要判断是否是模块里声明的逻辑在 isDeclared() 内,需要准确提取出 jar 里的 groupdId + artifactId, 但当前只提取了 artifactId, 如果基座和模块里有 groupId 不同 artifactId 相同的依赖,会被误认为也是允许委托加载的。