Skip to content
New issue

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

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

Already on GitHub? Sign in 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启动和打包出来启动都没遇到,可能是并发问题,可以优化一下

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

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

No branches or pull requests

2 participants