首页 > 技术文章 > Nacos 自动更新配置不生效问题

hystrix 2021-08-02 17:44 原文

版本

Nacos 1.4.1

SpringCloud 2020.0.3


解决方案

bootstrap.properties 增加应用名配置即可

spring.application.name=service-product

(导致失效的原因可能有多种,如果上述解决方案无效,可以评论私信我具体版本)


自动更新原理

其实是借助spring重新加载配置的能力,当Nacos发现配置文件MD5不一致时,新增刷新事件,触发SpringCloud重新加载逻辑。

com.alibaba.nacos.api.config.listener.AbstractSharedListener#innerReceive    发布Refesh事件

public void innerReceive(String dataId, String group,
							String configInfo) {
						refreshCountIncrement();
						nacosRefreshHistory.addRefreshRecord(dataId, group, configInfo);
						// todo feature: support single refresh for listening
						applicationContext.publishEvent(
								new RefreshEvent(this, null, "Refresh Nacos config"));
						if (log.isDebugEnabled()) {
							log.debug(String.format(
									"Refresh Nacos config group=%s,dataId=%s,configInfo=%s",
									group, dataId, configInfo));
						}
					}

org.springframework.cloud.endpoint.event.RefreshEventListener#handle(org.springframework.cloud.endpoint.event.RefreshEvent) SpringApplication调用刷新入口

public void handle(RefreshEvent event) {
		if (this.ready.get()) { // don't handle events before app is ready
			log.debug("Event received " + event.getEventDesc());
			Set<String> keys = this.refresh.refresh();
			log.info("Refresh keys changed: " + keys);
		}
	}

org.springframework.boot.SpringApplication#applyInitializers 获取初始化类 如下

 org.springframework.cloud.bootstrap.BootstrapApplicationListener$AncestorInitializer@1491c218
 org.springframework.cloud.bootstrap.BootstrapApplicationListener$DelegatingEnvironmentDecryptApplicationInitializer@1a06e969
 org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration@1d443173  //Nacos的配置加载locate注册在这
 org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer@6a729f71
 org.springframework.boot.context.config.DelegatingApplicationContextInitializer@57ced7d3
 org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer@6a2234f6
 org.springframework.boot.context.ContextIdApplicationContextInitializer@7a9fa37c
 org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer@35cd7790
 org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer@141c4eb5
 org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer@6fe25d44
 org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener@68618787

com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#locate 这里获取应用名 只能获取到bootstrap中配置的

原因是springCloud正常启动时会先加载application.yml,而刷新配置时不会

String dataIdPrefix = nacosConfigProperties.getPrefix();
		if (StringUtils.isEmpty(dataIdPrefix)) {
			dataIdPrefix = name;
		}

		if (StringUtils.isEmpty(dataIdPrefix)) {
			dataIdPrefix = env.getProperty("spring.application.name");
		}

com.alibaba.nacos.api.config.ConfigService#getConfig 这个是真正获取配置的接口

 

推荐阅读