-
Notifications
You must be signed in to change notification settings - Fork 314
Description
Issue Description
问题版本:问题发现版本nacos-spring-context-1.1.1.jar, 目前最新的release版本为nacos-spring-context-1.1.2.jar问题仍存在
问题表现: 系统启动后, 配置了@NacosValue autoRefresh的nacos 配置条目有固定次数配置变更无法autoRefresh
Describe what happened (or what feature you want)
1 问题原因
1.1 在spring容器启动时, 会生成针对nacos配置刷新的监听器bean, 在nacos配置发生变更时, 监听器会遍历所有使用@NacosValue autorefresh的bean列表, 通过属性或者方法设置对应key的新value
1.2 如果存在nacos配置条目的value包含$,并且配置了@NacosValue autoRefresh监听, 在进行占位符替换时, 会校验$后面必需是"{"或者数字"1~9" ,否则会抛出异常, 导致设置配置新值的循环中断, 排在该配置条目后面的配置无法刷新
1.3 由于每次占位符替换前会设置新的md5值到对应监听key上, 比对是基于key新旧值的md5值做的比对,故只会在第一次监听刷新时产生异常中断, 后续其他key的value刷新, 会认为value值包含$的key已刷新成功, 直接跳过, 故后续其他配置条目更改时刷新不会受到影响
2 问题影响
2.1 配置条目的value包含$并且$后续字符不是{或者数字1~9 的配置项无法自动刷新
2.2 不定数量的其他配置了autoRefresh的配置条目, 在启动后,前几次变更配置无法自动刷新, 无法自动刷新的次数同应用中监听的value包含$并且$后续字符不是{或者数字1~9 的配置条目数一致.
2.3 如果同时变更value包含$并且$后续字符不是{或者数字1~9 的配置条目和其他条目, 则均无法刷新成功
2.4 异常堆栈

3 复现方法
3.1 nacos中新建application.properties文件, 录入如下配置
demoConfigItem0=qtest0
demoConfigItem1={"password":"(.*password):|=(?!ENC[(][a-zA-Z0-9]+[)])(?![$][{].+[}])(.+)"}
demoConfigItem2=dtest2
demoConfigItem3=atest3
demoConfigItem4=pre,prod,green
3.2 在bean中监听所有的配置条目, 启动服务

3.3 将上述配置改为
demoConfigItem0=qtest+c0
demoConfigItem1={"password":"(.*password):|=(?!ENC[(][a-zA-Z0-9]+[)])(?![$][{].+[}])(.+)"}
demoConfigItem2=dtest2+c2
demoConfigItem3=atest3+c3
demoConfigItem4=pre,prod,green+c4
可以看到, 只有部分key能刷新成功
3.4 再次将上述配置改为
demoConfigItem0=qtest+c0+c01
demoConfigItem1={"password":"(.*password):|=(?!ENC[(][a-zA-Z0-9]+[)])(?![$][{].+[}])(.+)"}
demoConfigItem2=dtest2+c2+c21
demoConfigItem3=atest3+c3+c31
demoConfigItem4=pre,prod,green+c4+c41
可以看到,所有key都能能刷新成功
3.5 再次将上述配置改为
demoConfigItem0=qtest+c0+c01+c02
demoConfigItem1={"password":"(.*password):|=(?!ENC[(][a-zA-Z0-9]+[)])(?![$][{].+[}])(.+)"}+c12
demoConfigItem2=dtest2+c2+c21+c22
demoConfigItem3=atest3+c3+c31+c32
demoConfigItem4=pre,prod,green+c4+c41+c42
可以看到,所有key均刷新不成功
Describe what you expected to happen
问题主要原因是配置包含$的value值时, 在进行占位符替换时, 有异常抛出导致刷新配置的循环中断, 并且异常被当作ignore异常被吞掉
希望做如下改进:
改进方案1
1、配置包含$的value值时, 在进行占位符替换时, 有异常抛出, 将异常信息以error日志的输出出来, 便于问题排查
2、异常的try catch放到每一个配置条目value值刷新的内部, 避免某一个刷新异常影响其他配置条目的刷新
改进方案2
1、 不使用jdk原生的replaceAll方法进行占位符替换, 自定义占位符替换方法, 能够兼容$后续字符不是{或者数字1~9的情况
How to reproduce it (as minimally and precisely as possible)
在NacosValueAnnotationBeanPostProcessor类的下图位置进行try catch, 输出error日志
