Dubbo默认使用令牌桶算法实现限流,令牌桶相关代码在org.apache.dubbo.rpc.filter.tps.StatItem类中。StatItem类使用一个AutomicInteger对象管理令牌,管理令牌的主要代码如下:
int value = token.get();
boolean flag = false;
while (value > 0 && !flag) {
flag = token.compareAndSet(value, value - 1);
value = token.get();
}
return flag;
这段代码的功能是判断是否还有剩余令牌,并把令牌数减1。
用AutomicInteger类的decrementAndGet方法也能达到类似的效果,并且代码量更少,代码如下:
return token.decrementAndGet() >= 0;
但是Dubbo中的代码有以下两个好处:
-
Dubbo代码所用的compareAndSet方法,性能上优于decrementAndGet,compareAndSet只需要调1次JNI方法,而decrementAndGet要2次。至于代码中的两次get方法调用,是直接返回当前值,可以忽略不计。
-
在令牌已经用完的情况下,Dubbo所采用的代码不需要更新token的值,而decrementAndGet方法每次调用都需要更新令牌计数值,需要调用2次JNI方法才能完成。