Open zhoujinsy opened 8 months ago
问题版本:问题发现版本nacos-spring-context-1.1.1.jar, 目前最新的release版本为nacos-spring-context-1.1.2.jar问题仍存在 问题表现: 系统启动后, 配置了@NacosValue autoRefresh的nacos 配置条目有固定次数配置变更无法autoRefresh
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均刷新不成功
问题主要原因是配置包含$的value值时, 在进行占位符替换时, 有异常抛出导致刷新配置的循环中断, 并且异常被当作ignore异常被吞掉 希望做如下改进: 改进方案1 1、配置包含$的value值时, 在进行占位符替换时, 有异常抛出, 将异常信息以error日志的输出出来, 便于问题排查 2、异常的try catch放到每一个配置条目value值刷新的内部, 避免某一个刷新异常影响其他配置条目的刷新 改进方案2 1、 不使用jdk原生的replaceAll方法进行占位符替换, 自定义占位符替换方法, 能够兼容$后续字符不是{或者数字1~9的情况
在NacosValueAnnotationBeanPostProcessor类的下图位置进行try catch, 输出error日志
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)
Describe what you expected to happen
How to reproduce it (as minimally and precisely as possible)
在NacosValueAnnotationBeanPostProcessor类的下图位置进行try catch, 输出error日志![image](https://github.com/nacos-group/nacos-spring-project/assets/33095021/7581a340-92a3-49fa-9d23-9001396a0d81)