sofastack / sofa-serverless

a framework to enabe app architecture evolve from monolithic to microservices smoothly by involving modular and macroservices architecture.
https://sofaserverless.gitee.io/home/
Apache License 2.0
115 stars 41 forks source link

arklet场景下使用logback组件存在冲突导致应用启动失败 #358

Closed qixiaobo closed 10 months ago

qixiaobo commented 11 months ago

Describe the question or bug

ark-serverless 0.5.5 之后支持了arklet并行加速静态发布 https://github.com/sofastack/sofa-serverless/pull/324 当biz使用logback组件时出现logback冲突 导致biz启动失败

Expected behavior

biz正常启动

Actual behavior

部分biz会报错

2023-11-30 17:44:06.615 ERROR 49221 --- [rk-biz-ops-0-T3] o.s.boot.SpringApplication               : Application startup failed

java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[security] - 'FileNamePattern' option has the same value "/Users/qixiaobo/work/sofa-engine/logs/security.log.%d{yyyy-MM-dd}" as that given for appender [security] defined earlier.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[security] - Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[security] - For more information, please visit http://logback.qos.ch/codes.html#earlier_fa_collision
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[file] - 'FileNamePattern' option has the same value "/Users/qixiaobo/work/sofa-engine/logs/passport.log.%d{yyyy-MM-dd}" as that given for appender [file] defined earlier.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[file] - Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[file] - For more information, please visit http://logback.qos.ch/codes.html#earlier_fa_collision
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:162)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:81)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:59)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:115)
at org.springframework.boot.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:303)
at org.springframework.boot.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:276)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:239)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:212)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:122)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org. springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:325)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:296)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:187)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:102)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:68)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:122)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:325)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:296)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
at com.f6car.goods.Application.main(Application.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.alipay.sofa.ark.bootstrap.MainMethodRunner.run(MainMethodRunner.java:48)
at com.alipay.sofa.ark.container.model.BizModel.start(BizModel.java:292)
at com.alipay.sofa.ark.api.ArkClient.installBiz(ArkClient.java:168)
at com.alipay.sofa.ark.api.ArkClient.installOperation(ArkClient.java:343)
at com.alipay.sofa.ark.api.ArkClient.installOperation(ArkClient.java:328)
at com.alipay.sofa.serverless.arklet.core.ops.UnifiedOperationServiceImpl.safeBatchInstall(UnifiedOperationServiceImpl.java:74)
at com.alipay.sofa.serverless.arklet.core.ops.UnifiedOperationServiceImpl.lambda$batchInstall$0(UnifiedOperationServiceImpl.java:95)
at java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1604)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

2023-11-30 17:44:06.615 ERROR 49221 --- [rk-biz-ops-0-T3] o.s.boot.SpringApplication               : Application startup failed

Steps to reproduce

Steps to reproduce the problem:

Screenshots

If applicable, add screenshots to help explain your problem.

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

Environment

qixiaobo commented 11 months ago

从代码中可以看到 LogbackReInitializer支持reinit 因此biz加载时会执行 但是其持有的是通一个LoggingContext 导致后续logging会出现依赖检查duplicate出现失败【可以理解成共享变量】


    private boolean innerCheckForFileNamePatternCollisionInPreviousRFA(FileNamePattern fileNamePattern) {
        boolean collisionsDetected = false;
        @SuppressWarnings("unchecked")
        Map<String, FileNamePattern> map = (Map<String, FileNamePattern>) context.getObject(CoreConstants.RFA_FILENAME_PATTERN_COLLISION_MAP);
        if (map == null) {
            return collisionsDetected;
        }
        for (Entry<String, FileNamePattern> entry : map.entrySet()) {
            if (fileNamePattern.equals(entry.getValue())) {
                addErrorForCollision("FileNamePattern", entry.getValue().toString(), entry.getKey());
                collisionsDetected = true;
            }
        }
        if (name != null) {
            map.put(getName(), fileNamePattern);
        }
        return collisionsDetected;
    }
qixiaobo commented 11 months ago

可以看到实际可以通过更换 logback.ContextSelector

 /**
     * FOR INTERNAL USE. This method is intended for use by  StaticLoggerBinder.
     *  
     * @param defaultLoggerContext
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public void init(LoggerContext defaultLoggerContext, Object key) throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
                    IllegalAccessException, InvocationTargetException {
        if (this.key == null) {
            this.key = key;
        } else if (this.key != key) {
            throw new IllegalAccessException("Only certain classes can access this method.");
        }

        String contextSelectorStr = OptionHelper.getSystemProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR);
        if (contextSelectorStr == null) {
            contextSelector = new DefaultContextSelector(defaultLoggerContext);
        } else if (contextSelectorStr.equals("JNDI")) {
            // if jndi is specified, let's use the appropriate class
            contextSelector = new ContextJNDISelector(defaultLoggerContext);
        } else {
            contextSelector = dynamicalContextSelector(defaultLoggerContext, contextSelectorStr);
        }
    }
qixiaobo commented 11 months ago

目前看到已经有pr在跟进了 https://github.com/sofastack/sofa-serverless/pull/305