|
|
|
@ -2,9 +2,9 @@
|
|
|
|
|
|
|
|
|
|
Sentinel 中漏桶算法通过 RateLimiterController 来实现,在漏桶算法中,会记录上一个请求的到达时间,如果新到达的请求与上一次到达的请求之间的时间差小于限流配置所规定的最小时间,新到达的请求将会排队等待规定的最小间隔到达,或是直接失败。
|
|
|
|
|
|
|
|
|
|
```Java
|
|
|
|
|
```java
|
|
|
|
|
@Override
|
|
|
|
|
public boolean canPass(Node node, int acquireCount, boolean prioritized) {
|
|
|
|
|
public boolean canPass(Node node, int acquireCount, boolean prioritized) {
|
|
|
|
|
if (acquireCount <= 0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -48,7 +48,7 @@ Sentinel 中漏桶算法通过 RateLimiterController 来实现,在漏桶算法
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Sentinel 中令牌桶算法的实现
|
|
|
|
@ -56,24 +56,24 @@ Sentinel 中漏桶算法通过 RateLimiterController 来实现,在漏桶算法
|
|
|
|
|
在 Sentinel 中,令牌桶算法通过 WarmUpController 类实现。在这个情况下,当配置每秒能通过多少请求后,那么在这里 sentinel 也会每秒往桶内添加多少的令牌。当一个请求进入的时候,将会从中移除一个令牌。由此可以得出,桶内的令牌越多,也说明当前的系统利用率越低。因此,当桶内的令牌数量超过某个阈值后,那么当前的系统可以称之为处于`饱和`状态。
|
|
|
|
|
当系统处于 `饱和`状态的时候,当前允许的最大 qps 将会随着剩余的令牌数量减少而缓慢增加,达到为系统预热热身的目的。
|
|
|
|
|
|
|
|
|
|
```Java
|
|
|
|
|
this.count = count;
|
|
|
|
|
```java
|
|
|
|
|
this.count = count;
|
|
|
|
|
|
|
|
|
|
this.coldFactor = coldFactor;
|
|
|
|
|
this.coldFactor = coldFactor;
|
|
|
|
|
|
|
|
|
|
warningToken = (int)(warmUpPeriodInSec * count) / (coldFactor - 1);
|
|
|
|
|
warningToken = (int)(warmUpPeriodInSec * count) / (coldFactor - 1);
|
|
|
|
|
|
|
|
|
|
maxToken = warningToken + (int)(2 * warmUpPeriodInSec * count / (1.0 + coldFactor));
|
|
|
|
|
maxToken = warningToken + (int)(2 * warmUpPeriodInSec * count / (1.0 + coldFactor));
|
|
|
|
|
|
|
|
|
|
slope = (coldFactor - 1.0) / count / (maxToken - warningToken);
|
|
|
|
|
slope = (coldFactor - 1.0) / count / (maxToken - warningToken);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
其中 count 是当前 qps 的阈值。coldFactor 则为冷却因子,warningToken 则为警戒的令牌数量,warningToken 的值为(热身时间长度 _ 每秒令牌的数量) / (冷却因子 - 1)。maxToken 则是最大令牌数量,具体的值为 warningToken 的值加上 (2 _ 热身时间长度 _ 每秒令牌数量) / (冷却因子 + 1)。当当前系统处于热身时间内,其允许通过的最大 qps 为 1 / (超过警戒数的令牌数 _ 斜率 slope + 1 / count),而斜率的值为(冷却因子 - 1) / count / (最大令牌数 - 警戒令牌数)。
|
|
|
|
|
举个例子: count = 3, coldFactor = 3,热身时间为 4 的时候,警戒令牌数为 6,最大令牌数为 12,当剩余令牌处于 6 和 12 之间的时候,其 slope 斜率为 1 / 9。 那么当剩余令牌数为 9 的时候的允许 qps 为 1.5。其 qps 将会随着剩余令牌数的不断减少而直到增加到 count 的值。
|
|
|
|
|
|
|
|
|
|
```Java
|
|
|
|
|
@Override
|
|
|
|
|
public boolean canPass(Node node, int acquireCount, boolean prioritized) {
|
|
|
|
|
```java
|
|
|
|
|
@Override
|
|
|
|
|
public boolean canPass(Node node, int acquireCount, boolean prioritized) {
|
|
|
|
|
long passQps = (long) node.passQps();
|
|
|
|
|
|
|
|
|
|
long previousQps = (long) node.previousPassQps();
|
|
|
|
@ -97,9 +97,9 @@ Sentinel 中漏桶算法通过 RateLimiterController 来实现,在漏桶算法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void syncToken(long passQps) {
|
|
|
|
|
protected void syncToken(long passQps) {
|
|
|
|
|
long currentTime = TimeUtil.currentTimeMillis();
|
|
|
|
|
currentTime = currentTime - currentTime % 1000;
|
|
|
|
|
long oldLastFillTime = lastFilledTime.get();
|
|
|
|
@ -119,9 +119,9 @@ Sentinel 中漏桶算法通过 RateLimiterController 来实现,在漏桶算法
|
|
|
|
|
lastFilledTime.set(currentTime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long coolDownTokens(long currentTime, long passQps) {
|
|
|
|
|
private long coolDownTokens(long currentTime, long passQps) {
|
|
|
|
|
long oldValue = storedTokens.get();
|
|
|
|
|
long newValue = oldValue;
|
|
|
|
|
|
|
|
|
@ -135,5 +135,5 @@ Sentinel 中漏桶算法通过 RateLimiterController 来实现,在漏桶算法
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Math.min(newValue, maxToken);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|