Dubbo源碼解析——限流

Dubbo限流

Dubbo的限流做用於提供方。能夠在高併發的狀況,保證系統的穩定性、安全性。避免讓系統被流量壓垮,致使總體服務不可用。java

實踐

提供者添加相似配置算法

<dubbo:service
  interface="com.huang.yuan.api.service.DemoService"
  ref="demoServiceImpl"
  version="1.0"
  delay="5000"
  filter="tps">
  <dubbo:parameter key="tps" value="1"/>
  <dubbo:parameter key="tps.interval" value="1000"/>  
</dubbo:service>

添加filter及dubbo paramter,表示每tps.interval的時間間隔內,能執行tps個請求。api

消費方同時發出10個請求數組

@Test
public void testdada() throws Exception {
  for (int i = 0; i < 10; i++) {
    new Thread(()->{
      demoService.test("huangyuan");
    }).start();
  }

  Thread.sleep(1100000);
}

提供方限制流量,多餘的請求將拋出異常:安全

image-20191214131831430

源碼

令牌桶算法

Dubbo默認使用令牌桶算法實現限流。某段時間內,桶裏面只能放進n個令牌,而後來一個請求就減小一個令牌,若是桶裏面的令牌沒有了,則不能繼續執行請求。併發

限流經過com.alibaba.dubbo.rpc.filter.TpsLimitFilter實現。高併發

首先從URL中獲取配置的限制,限制由兩個參數組成,表示在interval毫秒的時間內容許執行rate個調用。spa

默認週期是60秒,不限制速率。code

public boolean isAllowable() {

  // 獲取如今的時間
  long now = System.currentTimeMillis();

  // 當通過了interval時間間隔
  if (now > lastResetTime + interval) {

    // 從新設置token令牌的個數
    token.set(rate);

    // 從如今開始,通過interval的時間
    lastResetTime = now;
  }

  // 獲取令牌的值
  int value = token.get();

  boolean flag = false;

  // 使用CAS實現樂觀鎖
  while (value > 0 && !flag) {

    // 可以執行請求,則令牌減一
    flag = token.compareAndSet(value, value - 1);

    value = token.get();
  }

  return flag;
}
相關文章
相關標籤/搜索