聊聊dubbo的TPSLimiter

本文主要研究一下dubbo的TPSLimiterjava

TPSLimiter

dubbo-2.7.2/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/TPSLimiter.javagit

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);

}
  • TPSLimiter定義了isAllowable方法

DefaultTPSLimiter

dubbo-2.7.2/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiter.javagithub

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;
    }

}
  • DefaultTPSLimiter實現了TPSLimiter,它使用ConcurrentHashMap來存儲StatItem,其key爲URL中的serviceKey;isAllowable方法從URL中讀取tps參數,默認爲-1,小於0則從ConcurrentHashMap中移除,大於0則建立或者獲取StatItem,調用StatItem的isAllowable(重置或遞減token並返回結果)

StatItem

dubbo-2.7.2/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/StatItem.javaapache

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;
    }

}
  • StatItem定義了LongAdder類型的token,其isAllowable方法會判斷是否須要重置token,若是須要則使用buildLongAdder重置token,不須要的話則在token.sum() < 0時返回false,若是大於等於0則遞減token

小結

  • TPSLimiter定義了isAllowable方法
  • DefaultTPSLimiter實現了TPSLimiter,它使用ConcurrentHashMap來存儲StatItem,其key爲URL中的serviceKey;isAllowable方法從URL中讀取tps參數,默認爲-1,小於0則從ConcurrentHashMap中移除,大於0則建立或者獲取StatItem,調用StatItem的isAllowable(重置或遞減token並返回結果)
  • StatItem定義了LongAdder類型的token,其isAllowable方法會判斷是否須要重置token,若是須要則使用buildLongAdder重置token,不須要的話則在token.sum() < 0時返回false,若是大於等於0則遞減token

doc

相關文章
相關標籤/搜索