Java限流——RateLimiter使用


概要

在大數據量高並發訪問時,經常會出現服務或接口面對暴漲的請求而不可用的情況,甚至引發連鎖反映導致整個系統崩潰。此時你需要使用的技術手段之一就是限流,當請求達到一定的並發數或速率,就進行等待、排隊、降級、拒絕服務等。在限流時,常見的兩種算法是漏桶和令牌桶算法算法。

限流算法

令牌桶(Token Bucket)、漏桶(leaky bucket)和計數器算法是最常用的三種限流的算法。

1. 令牌桶算法

令牌桶算法的原理是系統會以一個恆定的速度往桶里放入令牌,而如果請求需要被處理,則需要先從桶里獲取一個令牌,當桶里沒有令牌可取時,則拒絕服務。 當桶滿時,新添加的令牌被丟棄或拒絕。

優點:能處理瞬間增大的流量,比如現在正常情況下每秒產生5個令牌,在預制了5個令牌,如果一瞬間流量為一秒8個令牌,首先這一秒正常能生成5個令牌,在加上預制了5個令牌,所以可以處理這個瞬間流量

public class RateLimiterDemo {
    // 每秒生成5個令牌,預制5個令牌
    private static RateLimiter limiter = RateLimiter.create(5);
    
 
    public static void exec() {
        // limiter.acquire() 表示消費一個令牌。當桶中有足夠的令牌時,則直接返回0,否則阻塞,直到 
        // 有可用的令牌數才返回,返回的值為阻塞的時間
        // limiter.acquire(1); // 如果沒有令牌則阻塞
        if(limiter.tryAcquire()) { // 有令牌則返回true
            // 處理核心邏輯
        } else {
       
            // 可以放到隊列里等待,也可以直接拒接請求,返回錯誤界面(稍后重試等)
        }
    }
}

漏桶算法

它的主要目的是控制數據注入到網絡的速率,平滑網絡上的突發流量,數據可以以任意速度流入到漏桶中。漏桶算法提供了一種機制,通過它,突發流量可以被整形以便為網絡提供一個穩定的流量。 漏桶可以看作是一個帶有常量服務時間的單服務器隊列,如果漏桶為空,則不需要流出水滴,如果漏桶(包緩存)溢出,那么水滴會被溢出丟棄。

缺點:處理不了瞬間增大的流量

public class RateLimiterDemo {
   
    // 10-預熱時間 TimeUtil.MILLISECONDS-時間單位  5-速率
    private static RateLimiter limiter = RateLimiter.create(5, 10, TimeUtil.MILLISECONDS);
    
 
    public static void exec() {
        // limiter.acquire() 表示消費一個令牌。當桶中有足夠的令牌時,則直接返回0,否則阻塞,直到 
        // 有可用的令牌數才返回,返回的值為阻塞的時間
        // limiter.acquire(1); // 如果沒有令牌則阻塞
        if(limiter.tryAcquire()) { // 有令牌則返回true
            // 處理核心邏輯
        } else {
       
            // 可以放到隊列里等待,也可以直接拒接請求,返回錯誤界面(稍后重試等)
        }
    }
}
View Code

 

概要

在大數據量高並發訪問時,經常會出現服務或接口面對暴漲的請求而不可用的情況,甚至引發連鎖反映導致整個系統崩潰。此時你需要使用的技術手段之一就是限流,當請求達到一定的並發數或速率,就進行等待、排隊、降級、拒絕服務等。在限流時,常見的兩種算法是漏桶和令牌桶算法算法。

限流算法

令牌桶(Token Bucket)、漏桶(leaky bucket)和計數器算法是最常用的三種限流的算法。

1. 令牌桶算法

令牌桶算法的原理是系統會以一個恆定的速度往桶里放入令牌,而如果請求需要被處理,則需要先從桶里獲取一個令牌,當桶里沒有令牌可取時,則拒絕服務。 當桶滿時,新添加的令牌被丟棄或拒絕。

優點:能處理瞬間增大的流量,比如現在正常情況下每秒產生5個令牌,在預制了5個令牌,如果一瞬間流量為一秒8個令牌,首先這一秒正常能生成5個令牌,在加上預制了5個令牌,所以可以處理這個瞬間流量

  1.  
    public class RateLimiterDemo {
  2.  
    // 每秒生成5個令牌,預制5個令牌
  3.  
    private static RateLimiter limiter = RateLimiter.create( 5);
  4.  
     
  5.  
     
  6.  
    public static void exec() {
  7.  
    // limiter.acquire() 表示消費一個令牌。當桶中有足夠的令牌時,則直接返回0,否則阻塞,直到
  8.  
    // 有可用的令牌數才返回,返回的值為阻塞的時間
  9.  
    // limiter.acquire(1); // 如果沒有令牌則阻塞
  10.  
    if(limiter.tryAcquire()) { // 有令牌則返回true
  11.  
    // 處理核心邏輯
  12.  
    } else {
  13.  
     
  14.  
    // 可以放到隊列里等待,也可以直接拒接請求,返回錯誤界面(稍后重試等)
  15.  
    }
  16.  
    }
  17.  
    }

漏桶算法

它的主要目的是控制數據注入到網絡的速率,平滑網絡上的突發流量,數據可以以任意速度流入到漏桶中。漏桶算法提供了一種機制,通過它,突發流量可以被整形以便為網絡提供一個穩定的流量。 漏桶可以看作是一個帶有常量服務時間的單服務器隊列,如果漏桶為空,則不需要流出水滴,如果漏桶(包緩存)溢出,那么水滴會被溢出丟棄。

缺點:處理不了瞬間增大的流量

  1.  
    public class RateLimiterDemo {
  2.  
     
  3.  
    // 10-預熱時間 TimeUtil.MILLISECONDS-時間單位 5-速率
  4.  
    private static RateLimiter limiter = RateLimiter.create( 5, 10, TimeUtil.MILLISECONDS);
  5.  
     
  6.  
     
  7.  
    public static void exec() {
  8.  
    // limiter.acquire() 表示消費一個令牌。當桶中有足夠的令牌時,則直接返回0,否則阻塞,直到
  9.  
    // 有可用的令牌數才返回,返回的值為阻塞的時間
  10.  
    // limiter.acquire(1); // 如果沒有令牌則阻塞
  11.  
    if(limiter.tryAcquire()) { // 有令牌則返回true
  12.  
    // 處理核心邏輯
  13.  
    } else {
  14.  
     
  15.  
    // 可以放到隊列里等待,也可以直接拒接請求,返回錯誤界面(稍后重試等)
  16.  
    }
  17.  
    }
  18.  
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM