版本
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 這個是真正獲取配置的接口