INTERVAL的动态调整
- Dominant language
- Java
- Stars
- 23.1k
- Forks
- 8.1k
- PR merge metrics
- No merged PRs in 30d
Description
我尝试着手动能够手动设置时间周期,但是有个问题让我百思不得解。
我动态修改了这个周期,只能针对没有过之前,如果之前该资源有应用了Sentinel,那么修改就无效。
比如,原始Interval默认为1,对于一个资源A,之前进行访问过,能够正常进行的流量控制。这时,我通过命令的方式修改了INTERVAL,比如修改为5,再访问A,但是A的INTERVAL还是1秒,并没有改变。但如果我访问资源B,B之前没有访问过,修改后的INTERVAL对B有效,B的流控规则就是我想要的效果。
我不知道哪里出的问题,贴出我修改的代码,能帮我看下吗?谢谢!
1、为IntervalProperty类增加一个专用于流量控制的 时间周期的规则修改的属性
```
public class IntervalProperty {
public static volatile int INTERVAL = 1;
//定义了FLOW_INTERVAL,专用于进行流量控制的 时间周期的规则。
public static volatile int FLOW_INTERVAL = 1;
public static void init(SentinelProperty dataSource) {
dataSource.addListener(new FlowIntervalPropertyListener());
}
private static class FlowIntervalPropertyListener implements PropertyListener {
public void configUpdate(Integer value) {
if (value == null) {
value = 1;
}
//目前只是想先动态修改FLOW_INTERVAL,下同
FLOW_INTERVAL = value;
RecordLog.info("Init flow interval: " + FLOW_INTERVAL);
}
public void configLoad(Integer value) {
if (value == null) {
value = 1;
}
FLOW_INTERVAL = value;
for (ClusterNode node : ClusterBuilderSlot.getClusterNodeMap().values()) {
node.reset();
}
RecordLog.info("Flow interval change received: " + FLOW_INTERVAL);
}
}
}
```
2、StatisticNode,仿照原来的逻辑增加了一个属性rollingCounterInSecond4Flow,修改了三个方法, 大致同旧,只是我想只是针对Flow的Interval。。省略其他方法
```
private transient Metric rollingCounterInSecond4Flow = new ArrayMetric(1000 / SampleCountProperty.sampleCount, IntervalProperty.FLOW_INTERVAL);
//我想这个方法就是重置统计吧
public void reset() {
rollingCounterInSecond = new ArrayMetric(1000 / SampleCountProperty.sampleCount,IntervalProperty.INTERVAL);
rollingCounterInSecond4Flow = new ArrayMetric(1000 / SampleCountProperty.sampleCount, IntervalProperty.FLOW_INTERVAL);
public long passQps() {
return rollingCounterInSecond4Flow.pass() / IntervalProperty.INTERVAL;
}
public void addPassRequest() {
rollingCounterInSecond.addPass();
rollingCounterInMinute.addPass();
rollingCounterInSecond4Flow.addPass();
}
```
3、一个简单的servlet能够通过url的方式修改Interval,使用了DynamicSentinelProperty。
```
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
DynamicSentinelProperty sentinelProperty = new DynamicSentinelProperty(Integer.parseInt(request.getParameter("interval")));
IntervalProperty.init(sentinelProperty);
response.getWriter().println(IntervalProperty.FLOW_INTERVAL);
}
```
主要逻辑为上
那么现在一个主要问就是,如果之前,我访问过某个服务。我动态修改了Interval后,并不起作用,就好像没有修改一样。 我修改了这个Interval之后,访问一个之前没有访问过的服务,那么这个Interval就生效了,能够达到我想要的效果。
**所以,我现在就是想不明白,为什么修改之后,之前访问过的资源就不起作用呢?是不是原Sentinel代码某处,还有什么地方保留者缓存什么?**
请指教! 谢谢!!
Contributor guide
Research direction
Start with IntervalProperty, StatisticNode, and DynamicSentinelProperty, then trace how existing and newly accessed resources obtain their interval and rolling metrics. Reproduce the reported difference between a previously accessed resource and a new resource, and determine whether the interval update reaches existing statistics; done means the cause and expected update behavior are documented or covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100