Spring Cloud Kubernetes - 启用配置重新加载时 Spring Boot 无法启动
Posted
技术标签:
【中文标题】Spring Cloud Kubernetes - 启用配置重新加载时 Spring Boot 无法启动【英文标题】:Spring Cloud Kubernetes - Spring boot fails to start when config reload is enabled 【发布时间】:2019-05-29 04:38:54 【问题描述】:我有这个演示项目,它打印从配置中读取的标签。
这是我的主要课程:
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class DemoApplication
private MyConfig config;
private DiscoveryClient discoveryClient;
@Autowired
public DemoApplication(MyConfig config, DiscoveryClient discoveryClient)
this.config = config;
this.discoveryClient = discoveryClient;
@RequestMapping("/")
public String info()
return config.getMessage();
public static void main(String[] args)
SpringApplication.run(DemoApplication.class, args);
@RequestMapping("/services")
public String services()
StringBuilder b = new StringBuilder();
discoveryClient.getServices().forEach((s) -> b.append(s).append(" , "));
return b.toString();
MyConfig
类是:
@Configuration
@ConfigurationProperties(prefix = "bean")
public class MyConfig
private String message = "a message that can be changed live";
public String getMessage()
return message;
public void setMessage(String message)
this.message = message;
bootstrap.properties
包含:
spring.application.name=demo
spring.cloud.kubernetes.config.name=demo
spring.cloud.kubernetes.config.enabled=true
spring.cloud.kubernetes.config.namespace=default
spring.cloud.kubernetes.reload.enabled=true
spring.cloud.kubernetes.reload.monitoring-config-maps=true
spring.cloud.kubernetes.reload.strategy=refresh
spring.cloud.kubernetes.reload.mode=event
management.endpoint.refresh.enabled=true
management.endpoints.web.exposure.include=*
以及build.gradle
中的依赖:
dependencies
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.cloud:spring-cloud-starter-kubernetes:+")
compile("org.springframework.cloud:spring-cloud-starter-kubernetes-config:+")
testCompile('org.springframework.boot:spring-boot-starter-test')
runtime("org.springframework.boot:spring-boot-properties-migrator")
我正在创建以kubectl create -f configmap-demo.yml
为内容的 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: demo
data:
bean.message: This is an info from k8
在 Kubernetes 中部署时,我在 Spring Boot 启动时收到以下错误:
2019-01-02 13:41:41.462 INFO 1 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$e13002af] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
2019-01-02 13:41:41.940 INFO 1 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: ConfigMapPropertySource name='configmap.demo.default'
2019-01-02 13:41:41.942 INFO 1 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: SecretsPropertySource name='secrets.demo.default'
2019-01-02 13:41:42.030 INFO 1 --- [ main] com.example.demo.DemoApplication : The following profiles are active: kubernetes
2019-01-02 13:41:43.391 INFO 1 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=416ee750-8ebb-365d-9114-12b51acaa1e0
2019-01-02 13:41:43.490 INFO 1 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$e13002af] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-01-02 13:41:43.917 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-01-02 13:41:43.952 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-01-02 13:41:43.953 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.13
2019-01-02 13:41:43.969 INFO 1 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2019-01-02 13:41:44.156 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-01-02 13:41:44.157 INFO 1 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2033 ms
2019-01-02 13:41:44.957 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-01-02 13:41:45.353 WARN 1 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'propertyChangeWatcher' defined in class path resource [org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration$ConfigReloadAutoConfigurationBeans.class]: Unsatisfied dependency expressed through method 'propertyChangeWatcher' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'configurationUpdateStrategy' defined in class path resource [org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration$ConfigReloadAutoConfigurationBeans.class]: Unsatisfied dependency expressed through method 'configurationUpdateStrategy' parameter 2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.context.restart.RestartEndpoint' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
2019-01-02 13:41:45.358 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2019-01-02 13:41:45.370 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2019-01-02 13:41:45.398 INFO 1 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-01-02 13:41:45.612 ERROR 1 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 2 of method configurationUpdateStrategy in org.springframework.cloud.kubernetes.config.reload.ConfigReloadAutoConfiguration$ConfigReloadAutoConfigurationBeans required a bean of type 'org.springframework.cloud.context.restart.RestartEndpoint' that could not be found.
The following candidates were found but could not be injected:
- Bean method 'restartEndpoint' in 'RestartEndpointWithIntegrationConfiguration' not loaded because @ConditionalOnClass did not find required class 'org.springframework.integration.monitor.IntegrationMBeanExporter'
- Bean method 'restartEndpointWithoutIntegration' in 'RestartEndpointWithoutIntegrationConfiguration' not loaded because @ConditionalOnEnabledEndpoint no property management.endpoint.restart.enabled found so using endpoint default
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.cloud.context.restart.RestartEndpoint' in your configuration.
如果我将 spring.cloud.kubernetes.reload.enabled
设置为 false
一切正常,并且配置映射被读取并投入使用。现在我的目标是在 configmap 更改但得到上面看到的异常时重新加载配置。我可以手动调用/actuator/refresh
,所以我认为这不是刷新端点的可用性不足。
我创建了一个演示项目,所有内容都包含在https://drive.google.com/open?id=1QbP8vePALLZ2hWQJArnyxrzSySuXHKiz。
【问题讨论】:
【参考方案1】:如果你设置management.endpoint.restart.enabled=true
它就会启动
消息告诉您它无法加载RestartEndpoint
bean。没有创建任何内容,因为可以通过两种方式加载它并且满足以下条件:
'RestartEndpointWithIntegrationConfiguration' 中的 Bean 方法 'restartEndpoint' 未加载,因为 @ConditionalOnClass 未找到所需的类 'org.springframework.integration.monitor.IntegrationMBeanExporter'
好吧,你没有使用 spring 集成,所以我猜你不想要这条路径 - 你想要另一条。
'RestartEndpointWithoutIntegrationConfiguration' 中的 Bean 方法 'restartEndpointWithoutIntegration' 未加载,因为 @ConditionalOnEnabledEndpoint 找不到属性 management.endpoint.restart.enabled 所以使用端点默认值
所以we need to setmanagement.endpoint.restart.enabled=true
,也是在official reload example project中设置的。如果不设置我们需要will not be loaded 的 RestartEndpoint bean。
【讨论】:
谢谢@Ryan Dawnson!出于某种原因,我假设刷新与重新启动相同......它现在运行良好。干杯!以上是关于Spring Cloud Kubernetes - 启用配置重新加载时 Spring Boot 无法启动的主要内容,如果未能解决你的问题,请参考以下文章
spring-cloud-kubernetes官方demo运行实战
部署 spring-cloud-kubernetes kubernetes-hello-world-example 失败
Spring Cloud Kubernetes 支持 Spring Cloud 负载均衡器吗?