热点参数修改问题
- Dominant language
- Java
- Stars
- 23.1k
- Forks
- 8.1k
- PR merge metrics
- No merged PRs in 30d
Description
spring-cloud-starter-alibaba-sentinel 2.2.5.RELEASE
com.alibaba.csp 1.8.0
需求:将 `resource=/test/test03/` 的数据count=3改为count=2
报错:
```
java.lang.NullPointerException
at com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager$RulePropertyListener.aggregateAndPrepareParamRules(ParamFlowRuleManager.java:141)
at com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager$RulePropertyListener.configUpdate(ParamFlowRuleManager.java:103)
at com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager$RulePropertyListener.configUpdate(ParamFlowRuleManager.java:99)
at com.alibaba.csp.sentinel.property.DynamicSentinelProperty.updateValue(DynamicSentinelProperty.java:57)
at com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager.loadRules(ParamFlowRuleManager.java:54)
at com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler.handle(ModifyParamFlowRulesCommandHandler.java:58)
at com.alibaba.csp.sentinel.transport.command.http.HttpEventTask.run(HttpEventTask.java:103)
```
sentinel-dashboard发送更新热点参数请求
```
curl -X POST 'http://10.16.50.244:18401/setParamFlowRules' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'data=[{"burstCount":0,"clusterConfig":{"fallbackToLocalWhenFail":true,"flowId":16,"sampleCount":10,"thresholdType":1,"windowIntervalMs":1000},"clusterMode":true,"controlBehavior":0,"count":2.0,"durationInSec":1,"grade":1,"limitApp":"default","maxQueueingTimeMs":0,"paramFlowItemList":[{"classType":"java.lang.String","count":1,"object":"1"}],"paramIdx":0,"resource":"/test/test03/*"}]'
```
sentinel客户端应用,ParamFlowRuleManager.loadRules()方法接收处理,在DynamicSentinelProperty.updateValue()方法中value = newValue;将新值赋给旧值,ParamFlowRuleManager.aggregateAndPrepareParamRules()方法,oldRuleList.removeAll(newRuleList);这里期望将新的值从旧的列表中删除,可是新值count=2,旧值count=3,故删除不了这也是问题的根本原因,接下来代码ParameterMetricStorage.getParamMetricForResource(resource).clearForRule(rule);报null,故修改失败,因为之前value = newValue;,所以ParamFlowRuleManager.PARAM_FLOW_RULES中的数据还是旧值,而全部变量value是新值,数据不一致。
我现在的解决思路:重写ParamFlowRuleManager.aggregateAndPrepareParamRules()方法逻辑,重写DynamicSentinelPropert。updateValue()方法,如果失败,保证value值还是旧值
Contributor guide
Research direction
Start with ParamFlowRuleManager.loadRules() and its RulePropertyListener.aggregateAndPrepareParamRules() path, then inspect DynamicSentinelProperty.updateValue() and the referenced ParameterMetricStorage cleanup. Reproduce the count change from 3 to 2 using the reported request and stack trace. Done means the update no longer throws a NullPointerException and the new rule value is applied consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100