dubboのTPSLimiterについて話します

4669 ワード

シーケンス
本文は主にdubboのTPSLimiterを研究する
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);

}
  • TPSLimiterはisAllowableメソッド
  • を定義する
    DefaultTPSLimiter
    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 stats = new ConcurrentHashMap();
    
        @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は、ConcurrentHashMapを使用してStatItemを格納するTPSLimiterを実現し、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.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;
        }
    
    }
  • StatItemはLongAdderタイプのtokenを定義し、isAllowableメソッドはtokenをリセットする必要があるかどうかを判断し、必要であればbuildLongAdderを使用してtokenをリセットし、必要でなければtoken.sum() < 0でfalseを返し、0以上であればtoken
  • を減算する
    小結
  • TPSLimiterはisAllowableメソッド
  • を定義する
  • DefaultTPSLimiterは、ConcurrentHashMapを使用してStatItemを格納するTPSLimiterを実現し、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
  • TPSLimiter
  • DefaultTPSLimiter
  • StatItem