本文主要研究一下dubbo的TPSLimiter
dubbo-2.7.2/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/TPSLimiter.java
public interface TPSLimiter { /** * judge if the current invocation is allowed by TPS rule * * @param url url * @param invocation invocation * @return true allow the current invocation, otherwise, return false */ boolean isAllowable(URL url, Invocation invocation); }
dubbo-2.7.2/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiter.java
public class DefaultTPSLimiter implements TPSLimiter { private final ConcurrentMap<String, StatItem> stats = new ConcurrentHashMap<String, StatItem>(); @Override public boolean isAllowable(URL url, Invocation invocation) { int rate = url.getParameter(TPS_LIMIT_RATE_KEY, -1); long interval = url.getParameter(TPS_LIMIT_INTERVAL_KEY, DEFAULT_TPS_LIMIT_INTERVAL); String serviceKey = url.getServiceKey(); if (rate > 0) { StatItem statItem = stats.get(serviceKey); if (statItem == null) { stats.putIfAbsent(serviceKey, new StatItem(serviceKey, rate, interval)); statItem = stats.get(serviceKey); } else { //rate or interval has changed, rebuild if (statItem.getRate() != rate || statItem.getInterval() != interval) { stats.put(serviceKey, new StatItem(serviceKey, rate, interval)); statItem = stats.get(serviceKey); } } return statItem.isAllowable(); } else { StatItem statItem = stats.get(serviceKey); if (statItem != null) { stats.remove(serviceKey); } } return true; } }
重置或递减token并返回结果
) dubbo-2.7.2/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/StatItem.java
class StatItem { private String name; private long lastResetTime; private long interval; private LongAdder token; private int rate; StatItem(String name, int rate, long interval) { this.name = name; this.rate = rate; this.interval = interval; this.lastResetTime = System.currentTimeMillis(); this.token = buildLongAdder(rate); } public boolean isAllowable() { long now = System.currentTimeMillis(); if (now > lastResetTime + interval) { token = buildLongAdder(rate); lastResetTime = now; } if (token.sum() < 0) { return false; } token.decrement(); return true; } public long getInterval() { return interval; } public int getRate() { return rate; } long getLastResetTime() { return lastResetTime; } long getToken() { return token.sum(); } @Override public String toString() { return new StringBuilder(32).append("StatItem ") .append("[name=").append(name).append(", ") .append("rate = ").append(rate).append(", ") .append("interval = ").append(interval).append("]") .toString(); } private LongAdder buildLongAdder(int rate) { LongAdder adder = new LongAdder(); adder.add(rate); return adder; } }
token.sum() < 0
时返回false,如果大于等于0则递减token 重置或递减token并返回结果 token.sum() < 0