Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

v3.0-develop分支最新的代码启动失败,存在多个线程同时创建一个Bean的问题 #13038

Closed
misakacoder opened this issue Jan 14, 2025 · 3 comments
Labels
Nacos3.0 Nacos 3.0 Architecture Evolution
Milestone

Comments

@misakacoder
Copy link
Contributor

misakacoder commented Jan 14, 2025

Describe the bug
问题描述:
使用v3.0-develop分支最新的代码,启动失败,存在多线程初始化同一个Bean的问题

关键日志:

2025-01-14T16:02:10.423+08:00  INFO 41412 --- [ection.reporter] o.s.b.f.s.DefaultListableBeanFactory     : Creating singleton bean 'connectionManager' in thread "nacos.plugin.control.connection.reporter" while other thread holds singleton lock for other beans [rpcConfigChangeNotifier, configChangeClusterSyncRequestHandler]
2025-01-14T16:02:10.427+08:00  INFO 41412 --- [ection.reporter] o.s.b.f.s.DefaultListableBeanFactory     : Creating singleton bean 'clientConnectionEventListenerRegistry' in thread "nacos.plugin.control.connection.reporter" while other thread holds singleton lock for other beans [rpcConfigChangeNotifier, rpcPushService, connectionManager, configChangeClusterSyncRequestHandler]
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'configChangeClusterSyncRequestHandler' defined in file [D:\Project\github\nacos\config\target\classes\com\alibaba\nacos\config\server\remote\ConfigChangeClusterSyncRequestHandler.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'rpcConfigChangeNotifier': Unsatisfied dependency expressed through field 'rpcPushService': Error creating bean with name 'rpcPushService': Unsatisfied dependency expressed through field 'connectionManager': Error creating bean with name 'connectionManager': Requested bean is currently in creation: Is there an unresolvable circular reference or an asynchronous initialization dependency?
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1377)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1214)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:289)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1122)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1093)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1030)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
	at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:149)
	at com.alibaba.nacos.bootstrap.NacosBootstrap.startCoreContext(NacosBootstrap.java:92)
	at com.alibaba.nacos.bootstrap.NacosBootstrap.main(NacosBootstrap.java:46)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'rpcConfigChangeNotifier': Unsatisfied dependency expressed through field 'rpcPushService': Error creating bean with name 'rpcPushService': Unsatisfied dependency expressed through field 'connectionManager': Error creating bean with name 'connectionManager': Requested bean is currently in creation: Is there an unresolvable circular reference or an asynchronous initialization dependency?
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:788)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:768)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:146)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:509)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1441)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:289)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:312)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1631)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1519)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
	... 20 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'rpcPushService': Unsatisfied dependency expressed through field 'connectionManager': Error creating bean with name 'connectionManager': Requested bean is currently in creation: Is there an unresolvable circular reference or an asynchronous initialization dependency?
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:788)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:768)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:146)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:509)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1441)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:289)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1573)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1519)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:785)
	... 37 common frames omitted
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'connectionManager': Requested bean is currently in creation: Is there an unresolvable circular reference or an asynchronous initialization dependency?
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:421)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:282)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1573)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1519)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:785)
	... 50 common frames omitted

问题代码:
com.alibaba.nacos.plugin.control.connection.ConnectionControlManager#startConnectionMetricsReport这个方法启动了一个定时器,在定时器中最后调用了ApplicationUtils.getBean(ConnectionManager.class)这个代码,此时主线程也在创建和初始化这个Bean,就出现了多个线程同时创建一个Bean的问题

    private void startConnectionMetricsReport() {
        executorService.scheduleWithFixedDelay(new ConnectionMetricsReporter(), 0, 3000, TimeUnit.MILLISECONDS);
    }
    class ConnectionMetricsReporter implements Runnable {
        
        @Override
        public void run() {
            Map<String, Integer> metricsTotalCount = metricsCollectorList.stream().collect(
                    Collectors.toMap(ConnectionMetricsCollector::getName, ConnectionMetricsCollector::getTotalCount));
            int totalCount = metricsTotalCount.values().stream().mapToInt(Integer::intValue).sum();
            
            Loggers.CONNECTION.info("ConnectionMetrics, totalCount = {}, detail = {}", totalCount, metricsTotalCount);
        }
    }
public class LongConnectionMetricsCollector implements ConnectionMetricsCollector {
    
    @Override
    public String getName() {
        return "long_connection";
    }
    
    @Override
    public int getTotalCount() {
        return ApplicationUtils.getBean(ConnectionManager.class).currentClientsCount();
    }
    
    @Override
    public int getCountForIp(String ip) {
        ConnectionManager connectionManager = ApplicationUtils.getBean(ConnectionManager.class);
        if (connectionManager.getConnectionForClientIp().containsKey(ip)) {
            return connectionManager.getConnectionForClientIp().get(ip).intValue();
        } else {
            return 0;
        }
    }
}

Expected behavior
A clear and concise description of what you expected to happen.

Actually behavior
A clear and concise description of what you actually to happen.

How to Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See errors

Desktop (please complete the following information):

  • OS: [e.g. Centos]
  • Version [e.g. nacos-server 1.3.1, nacos-client 1.3.1]
  • Module [e.g. naming/config]
  • SDK [e.g. original, spring-cloud-alibaba-nacos, dubbo]

Additional context
Add any other context about the problem here.

@KomachiSion KomachiSion added the Nacos3.0 Nacos 3.0 Architecture Evolution label Jan 14, 2025
@KomachiSion KomachiSion added this to the 3.0.0 milestone Jan 14, 2025
@KomachiSion
Copy link
Collaborator

我本地试了几次, 从idea启动和打包出来启动都没遇到,可能是并发问题,可以优化一下

@misakacoder
Copy link
Contributor Author

本地是启动的NacosBootstrap这个启动类嘛,我的操作系统是Windows。我上周启动这个类没这个问题,好像应该是支持GraalVM这个代码加进来后,就有问题了,我用2.0的代码测试了下,ConnectionManager类的构造函数先执行,ConnectionControlManager构造函数后执行,定时器执行时,ConnectionManager已经被Spring创建好了,就没这个问题,3.0的这2个类构造函数执行顺序就是反过来的。。。

@misakacoder
Copy link
Contributor Author

我本地试了几次, 从idea启动和打包出来启动都没遇到,可能是并发问题,可以优化一下

我来看看怎么改,我这里是稳定复现的,目前都是注释掉这个定时器才启动成功的

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Nacos3.0 Nacos 3.0 Architecture Evolution
Projects
None yet
Development

No branches or pull requests

2 participants