前言

apollo是一个十分风行的开源的配置核心我的项目,这里就不多介绍了。接触过apollo和运行过apollo的人必定都遇到过启动configService时抛异样了,而且100%会抛一个异样。起因是,在apollo的架构中configService既作为config服务,同时也承载了metaService的性能,所以这个模块,既作为eureka的服务端也是eureka的客户端,这就造成了利用启动时,eurekaServer未齐全启动,eurekaClient拉取注册表信息时就抛异样了。不过这个拉取动作是在独立的线程中运行的,独立于启动利用的主线程,所以异样并不影响利用的启动,这个问题也就始终从开源到留到了当初。目前,这个问题已被博主解决,正在合并pr中。

本文pr地址:https://github.com/ctripcorp/...

触发起因剖析

首先看下异样的信息,异样的信息比拟多,如下:

2020-12-23 09:55:19.882 ERROR 7022 --- [           main] c.n.d.s.t.d.RedirectingEurekaHttpClient  : Request execution errorcom.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused (Connection refused)    at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187)    at com.sun.jersey.api.client.filter.GZIPContentEncodingFilter.handle(GZIPContentEncodingFilter.java:123)    at com.netflix.discovery.EurekaIdentityHeaderFilter.handle(EurekaIdentityHeaderFilter.java:27)    at com.sun.jersey.api.client.Client.handle(Client.java:652)    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682)    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)    at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:509)    at com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient.getApplicationsInternal(AbstractJerseyEurekaHttpClient.java:194)    at com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient.getApplications(AbstractJerseyEurekaHttpClient.java:165)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)    at com.netflix.discovery.shared.transport.decorator.MetricsCollectingEurekaHttpClient.execute(MetricsCollectingEurekaHttpClient.java:73)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)    at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.executeOnNewServer(RedirectingEurekaHttpClient.java:118)    at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.execute(RedirectingEurekaHttpClient.java:79)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)    at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:120)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)    at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)    at com.netflix.discovery.DiscoveryClient.getAndStoreFullRegistry(DiscoveryClient.java:1051)    at com.netflix.discovery.DiscoveryClient.fetchRegistry(DiscoveryClient.java:965)    at com.netflix.discovery.DiscoveryClient.<init>(DiscoveryClient.java:414)    at com.netflix.discovery.DiscoveryClient.<init>(DiscoveryClient.java:269)    at org.springframework.cloud.netflix.eureka.CloudEurekaClient.<init>(CloudEurekaClient.java:63)    at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration.eurekaClient(EurekaClientAutoConfiguration.java:290)    at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration$$EnhancerBySpringCGLIB$$5cf7ced9.CGLIB$eurekaClient$2(<generated>)    at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration$$EnhancerBySpringCGLIB$$5cf7ced9$$FastClassBySpringCGLIB$$328872d8.invoke(<generated>)    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:365)    at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration$$EnhancerBySpringCGLIB$$5cf7ced9.eurekaClient(<generated>)    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 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:353)    at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:390)    at org.springframework.cloud.context.scope.GenericScope.get(GenericScope.java:184)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)    at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193)    at com.sun.proxy.$Proxy145.getApplications(Unknown Source)    at org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration.peerAwareInstanceRegistry(EurekaServerAutoConfiguration.java:164)    at org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration$$EnhancerBySpringCGLIB$$ef07d99b.CGLIB$peerAwareInstanceRegistry$5(<generated>)    at org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration$$EnhancerBySpringCGLIB$$ef07d99b$$FastClassBySpringCGLIB$$458f0ac6.invoke(<generated>)    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:365)    at org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration$$EnhancerBySpringCGLIB$$ef07d99b.peerAwareInstanceRegistry(<generated>)    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 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818)    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:724)    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:474)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583)    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1341)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277)    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265)    at com.ctrip.framework.apollo.configservice.ConfigServiceApplication.main(ConfigServiceApplication.java:33)Caused by: java.net.ConnectException: Connection refused (Connection refused)    at java.net.PlainSocketImpl.socketConnect(Native Method)    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)    at java.net.Socket.connect(Socket.java:606)    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144)    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134)    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610)    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445)    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835)    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:118)    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)    at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:173)    ... 107 common frames omitted2020-12-23 09:55:19.883  WARN 7022 --- [           main] c.n.d.s.t.d.RetryableEurekaHttpClient    : Request execution failed with message: java.net.ConnectException: Connection refused (Connection refused)2020-12-23 09:55:19.883 ERROR 7022 --- [           main] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_APOLLO-CONFIGSERVICE/172.26.203.178:apollo-configservice:8080 - was unable to refresh its cache! status = Cannot execute request on any known servercom.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server    at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)    at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77)    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)    at com.netflix.discovery.DiscoveryClient.getAndStoreFullRegistry(DiscoveryClient.java:1051)    at com.netflix.discovery.DiscoveryClient.fetchRegistry(DiscoveryClient.java:965)    at com.netflix.discovery.DiscoveryClient.<init>(DiscoveryClient.java:414)    at com.netflix.discovery.DiscoveryClient.<init>(DiscoveryClient.java:269)    at org.springframework.cloud.netflix.eureka.CloudEurekaClient.<init>(CloudEurekaClient.java:63)    at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration.eurekaClient(EurekaClientAutoConfiguration.java:290)    at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration$$EnhancerBySpringCGLIB$$5cf7ced9.CGLIB$eurekaClient$2(<generated>)    at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration$$EnhancerBySpringCGLIB$$5cf7ced9$$FastClassBySpringCGLIB$$328872d8.invoke(<generated>)    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:365)    at org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration$$EnhancerBySpringCGLIB$$5cf7ced9.eurekaClient(<generated>)    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 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:353)    at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:390)    at org.springframework.cloud.context.scope.GenericScope.get(GenericScope.java:184)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)    at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193)    at com.sun.proxy.$Proxy145.getApplications(Unknown Source)    at org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration.peerAwareInstanceRegistry(EurekaServerAutoConfiguration.java:164)    at org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration$$EnhancerBySpringCGLIB$$ef07d99b.CGLIB$peerAwareInstanceRegistry$5(<generated>)    at org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration$$EnhancerBySpringCGLIB$$ef07d99b$$FastClassBySpringCGLIB$$458f0ac6.invoke(<generated>)    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:365)    at org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration$$EnhancerBySpringCGLIB$$ef07d99b.peerAwareInstanceRegistry(<generated>)    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 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818)    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:724)    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:474)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583)    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1341)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277)    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265)    at com.ctrip.framework.apollo.configservice.ConfigServiceApplication.main(ConfigServiceApplication.java:33)

最终咱们就定位到这一行,定位问题的过程是一个非常复杂的事件。所以这里间接写明,并不是一开始我就晓得关键点在这里,这个须要平时多积攒知识面,能力疾速定位关键点

at com.netflix.discovery.DiscoveryClient.<init>(DiscoveryClient.java:414)。代码逻辑如下:if (clientConfig.shouldFetchRegistry() && !fetchRegistry(false)) {    fetchRegistryFromBackup();}

下面的异样就是这个中央触发的,在初始化eurekaClient时,会通过判断fetchRegistry来触发拉取eurekaServer端的注册表信息,然而这个时候eurekaServer还没筹备好,所以抛了如上的异样。fetchRegistry对应了Spring 初始化eurekaClient的一个配置,如:

//是否拉取注册表信息,如果配置为false,则代表只注册,通过eurekaClient获取不到任何实例eureka.client.fetch-registry=true

eurekaClient的结构

理解了异样触发的起因和触发的节点后,在来具体理解下eurekaClient在spring下是如何被加载的。间接定位到EurekaClientAutoConfiguration.java文件,找到如下的代码:

@Bean(destroyMethod = "shutdown")@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)@org.springframework.cloud.context.config.annotation.RefreshScope@Lazypublic EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config, EurekaInstanceConfig instance) {   manager.getInfo(); // force initialization return new CloudEurekaClient(manager, config, this.optionalArgs, this.context);}

能够看到EurekaClientConfig是从上下文中注入到这个办法的,而且这个办法贴上了@RefreshScope的标记,代表这个实例能够被动静的刷新,有了这两个个性,咱们的解决方案就根本出炉了。通过程序动态控制eurekaClient的fetchRegistry加载机会也就变得可行了。

施行解决方案

最终的解决方案分成了两个关键步骤,如下:

  • 1、configService启动前,设置fetchRegistry为false。
  • 2、监听EurekaClient的注册事件,判断是否注册胜利,注册胜利则从新设置fetchRegistry为true,刷新eurekaClient上下文

针对步骤一,间接批改configService模块的bootstrap.yml配置文件,新增fetchRegistry为false的配置,如:

eureka:  instance:    hostname: ${hostname:localhost}    preferIpAddress: true status-page-url-path: /info    health-check-url-path: /health  server:    peerEurekaNodesUpdateIntervalMs: 60000 enableSelfPreservation: false client:    serviceUrl:      # This setting will be overridden by eureka.service.url setting from ApolloConfigDB.ServerConfig or System Property # see com.ctrip.framework.apollo.biz.eureka.ApolloEurekaClientConfig defaultZone: http://${eureka.instance.hostname}:8080/eureka/    healthcheck:      enabled: true    eurekaServiceUrlPollIntervalSeconds: 60 fetch-registry: falsemanagement:  health:    status:      order: DOWN, OUT_OF_SERVICE, UNKNOWN, UP

针对步骤二,新增了一个eurekaClient的配置类,如:

/** * @author : kl * After startup, set FetchRegistry to true, refresh eureka client **/@Configuration@ConditionalOnProperty(value = "eureka.client.enabled", havingValue = "true", matchIfMissing = true)public class ConfigServerEurekaClientConfigure {    private static final String EUREKACLIENT_BEANNAME = "eurekaClient";    private final ApolloEurekaClientConfig eurekaClientConfig;    private final AtomicBoolean isRefresh = new AtomicBoolean(false);    private final RefreshScope refreshScope;    public ConfigServerEurekaClientConfigure(ApolloEurekaClientConfig eurekaClientConfig, RefreshScope refreshScope) {        this.eurekaClientConfig = eurekaClientConfig;        this.refreshScope = refreshScope;    }    @EventListener    public void listenEurekaInstanceRegisteredEvent(EurekaInstanceRegisteredEvent event) {        InstanceInfo.InstanceStatus status = event.getInstanceInfo().getStatus();        if (InstanceInfo.InstanceStatus.UP.equals(status) && !eurekaClientConfig.isFetchRegistry()) {            this.refreshEurekaClient();        }    }    private void refreshEurekaClient() {        if (isRefresh.compareAndSet(false, true)) {            eurekaClientConfig.setFetchRegistry(true);            refreshScope.refresh(EUREKACLIENT_BEANNAME);        }    }}

结语

通过革新后,存在了这么久的异样终于隐没了。整个过程还是有一些波折的,最后曾尝试过,自定义EurekaClient的初始化,妄想try住整个的实例化过程,接住异样自行处理,然而疏忽了fetchRegistry的过程是在一个新的线程里了。其次,最后的时候认为将fetchRegistry设置为false就ok了,而后在metaService服务获取configService时候啥也获取不到,才明确了fetchRegistry的真正用意。还尝试过将刷新EurekaClient的逻辑放在ApplicationRunner的run办法内,这个造成了后果时好时坏。最终随着对Eureka的深刻,才采纳了当初的计划,目前的计划还算完满。最初,心愿失去大家的测验反馈,早点合并到主干道,解决这个烦人的问题。