sofastack / sofa-ark

SOFAArk is a light-weight,java based classloader isolation framework.
https://www.sofastack.tech/projects/sofa-boot/sofa-ark-readme/
Apache License 2.0
1.57k stars 500 forks source link

静态合并部署com.alipay.sofa.ark.springboot.listener.ArkDeployStaticBizListener重复执行导致部署失败 #645

Closed davidzj closed 1 year ago

davidzj commented 1 year ago

Describe the bug

com.alipay.sofa.ark.springboot.listener.ArkDeployStaticBizListener 执行两次导致静态合并部署失败,使用动态部署确认可以成功部署

Expected behavior

com.alipay.sofa.ark.springboot.listener.ArkDeployStaticBizListener 只执行一次

Actual behavior

com.alipay.sofa.ark.springboot.listener.ArkDeployStaticBizListener 执行了两次

Steps to reproduce

第一次执行:

image image

第二次执行:

image image

Minimal yet complete reproducer code (or GitHub URL to code)

Environment

davidzj commented 1 year ago

补充一点,Master Biz包含Spring Cloud

gaosaroma commented 1 year ago

我用结合 spring boot 的静态合并部署的简单demo貌似没有遇到这个问题;这一段逻辑是这样的:ArkDeployStaticBizListener 类是在 master biz 启动时被加载的,类加载器和 master biz 的类加载保持一致,根据该语句:

// Only listen to the event when the master biz is started
        if (this.getClass().getClassLoader() != Thread.currentThread().getContextClassLoader()) {
            return;
        }

该 listener 的后续逻辑应当只会在 master biz 启动时触发,用来启动其余的业务biz。由于业务biz是由各自的 BizClassLoader 加载,所以这个语句直接return,不会在业务biz启动时触发该 listener 的后续逻辑。除非在 master biz 启动时 ContextRefreshEvent 被send了不止1次。这可能需要麻烦你再检查一下触发两次后续逻辑的原因了。

davidzj commented 1 year ago

Master Biz把Spring Cloud加上,比如用spring-cloud-config从nacos动态加载配置,就会复现了。参考这个文档:https://juejin.cn/post/6844904042292838414 ,一共是3次,sofa-ark的要保证在第一次不执行,第二次执行,第三次不执行。

原因: Spring Cloud创建了一个bootstrap的ApplicationContext(见org.springframework.cloud.bootstrap.BootstrapApplicationListener),并把当前ApplicationContext的parent设置为bootstrap ApplicationContext,bootstrap ApplicationContext 和当前ApplicationContext初始化完成之后均会发ContextRefreshedEvent,另外当前ApplicationContext发ContextRefreshedEvent时如果存在parent,也会同时调parent再发一次。

我这边写了段临时代码避免了这个问题,测试是可以成功的:

image

但是这个实现不太好,你们有更好的的办法处理这个问题吗?

davidzj commented 1 year ago

再补充一点,开启management,一样会执行多次 management.endpoint.health.show-details=always management.endpoints.jmx.exposure.include= management.endpoints.web.exposure.include= 需要这样改才能成功:

image
yuanyuancin commented 1 year ago

spring cloud和开启management 时带来的多 application context 问题,可以提个pr修复下~

yuanyuancin commented 1 year ago

@davidzj 欢迎加入我们的开发者写作群沟通 钉钉 搜索 SOFAArk 社区开发者协作群 ,群号 24970018417

lylingzhen commented 1 year ago

@davidzj 可以提一个修复的 PR 么?

lylingzhen commented 1 year ago

放在 Spring 生态治理中统一跟进。

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity in the last 30 days. It will be closed in the next 7 days unless it is tagged (pinned, good first issue or help wanted) or other activity occurs. Thank you for your contributions.

lvjing2 commented 1 year ago

统一放在这里解决跟进,https://github.com/sofastack/sofa-serverless/issues/213

qixiaobo commented 1 year ago

Same problem here