Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

通过@NacosValue autoRefreshed监听配置条目如果value包含"$"可能会导致autoRefreshed功能失效 #335

Open
zhoujinsy opened this issue Dec 29, 2023 · 0 comments

Comments

@zhoujinsy
Copy link

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 异常堆栈   

image
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中监听所有的配置条目, 启动服务
image
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日志
image

@zhoujinsy zhoujinsy changed the title @NacosValue的autoRefreshed监听value中包含"$"的配置条目会导致autoRefreshed功能失效 通过@NacosValue autoRefreshed监听配置条目中如果value包含"$"可能会导致autoRefreshed功能失效 Dec 29, 2023
@zhoujinsy zhoujinsy changed the title 通过@NacosValue autoRefreshed监听配置条目中如果value包含"$"可能会导致autoRefreshed功能失效 通过@NacosValue autoRefreshed监听配置条目如果value包含"$"可能会导致autoRefreshed功能失效 Dec 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant