INDEX
- §1 配置方式
- §1.1 springboot 配置
- §1.2 springcloud 配置
- §2 失效排查
- §2.1 常见失效场景
- §2.1.1 配置不配套
- §2.1.2 自动刷新未开启
- §2.1.3 依赖冲突
- §2.1.4 改错了配置文件
- §2.2 未知情况关键排查点
§1 配置方式
nacos 的配置中心主要有两套配置方式,配置方式不互相共通,需要配套配置
- springboot
- springcloud
§1.1 springboot 配置
依赖
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${nacos.version}</version>
</dependency>
自动刷新配置
# 注意 nacos 地址、用户名密码、group 等配置也要正确
nacos.config.auto-refresh=true
配置类
- 类上只需要
@Configuration
注解 - 字段使用
@NacosValue
,想开启自动刷新必须开启autoRefreshed
属性
@Configuration
public class XxxConfig{
@NacosValue(value = "${x.x.xxx}",autoRefreshed = true)
private Integer xxx;
}
§1.2 springcloud 配置
依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
自动刷新配置
# 注意 nacos 地址、用户名密码、group 等配置也要正确
spring.cloud.nacos.config.refresh-enabled=true
配置类
- 类上只需要
@Component
&@RefreshScope(重要)
- 字段照常使用
@Value
@Component
@RefreshScope
public class XxxConfig {
@Value(value = "${x.x.xxx}")
private String xxx;
}
§2 失效排查
§2.1 常见失效场景
§2.1.1 配置不配套
- springcloud +
@RefreshScope
+spring.cloud.nacos.config
配置前缀 - springboot +
@NacosValue
+nacos.config
配置前缀
§2.1.2 自动刷新未开启
可能是下列漏配
- springcloud
-spring.cloud.nacos.config.refresh-enabled=true
- 配置类上注解
@RefreshScope
- 配置类上注解
- springboot
nacos.config.auto-refresh=true
- 配置字段上注解
@NacosValue
@NacosValue
没开启autoRefresh
属性
§2.1.3 依赖冲突
项目中,极力推荐尽量排除所有依赖冲突,可以使用 xml文件里->Diagrams->Show Dependencies
试图排查:干掉尽可能多的红色虚线
阿里系依赖普遍对版本要求较高,高低版本不兼容情况相对叫较高
主要受影响的是下面的包,可在上图中搜索
依赖冲突可能导致部分类报 ClassNotDefineException
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
§2.1.4 改错了配置文件
通常发生在配置文件中手动指定了 data-ids
时,比如指定文件名 xx-test.yml
但当前环境是 dev
等
§2.2 未知情况关键排查点
nacos server 中配置修改后,会主动推送 NacosConfigReceivedEvent
至 NacosValueAnnotationBeanPostProcessor
,关键方法如下,有必要时可在此方法处断点观察
- 是否有事件
- 是否有新值
- 是否能找到 nacos 的配置点
- 修改逻辑是否正常执行
// enent 只用于触发,以前里面有 content,现在会直接将得到的新配置全文更新到 environment
// placeholderNacosValueTargetMap 即被 nacos 自动更新纳管的属性
@Override
public void onApplicationEvent(NacosConfigReceivedEvent event) {
for (Map.Entry<String, List<NacosValueTarget>> entry : placeholderNacosValueTargetMap
.entrySet()) {
// key 和 新值
String key = environment.resolvePlaceholders(entry.getKey());
String newValue = environment.getProperty(key);
if (newValue == null) {
continue;
}
// 某个属性的注入点
List<NacosValueTarget> beanPropertyList = entry.getValue();
for (NacosValueTarget target : beanPropertyList) {
// MD5 校验,已知不同版本对导致这里使用不同的类,变动相对频繁
String md5String = MD5Utils.md5Hex(newValue, "UTF-8");
boolean isUpdate = !target.lastMD5.equals(md5String);
if (isUpdate) {
target.updateLastMD5(md5String);
Object evaluatedValue = resolveNotifyValue(target.nacosValueExpr, key, newValue);
//注入新值
if (target.method == null) {
setField(target, evaluatedValue);
}
else {
setMethod(target, evaluatedValue);
}
}
}
}
}