RateLimiter 從概念上來說,速率限制器會在可配置的速率下分配許可證。數據庫
從最終用戶訪問安全的角度看,設想有人想暴力碰撞網站的用戶密碼;或者有人攻擊某個很耗費資源的接口;或者有人想從某個接口大量抓取數據。大部分 人都知道應該增長 Rate limiting,作請求頻率限制。從安全角度,這個可能也是大部分能想到,但不必定去作的薄弱環節。segmentfault
從整個架構的穩定性角度看,通常 SOA 架構的每一個接口的有限資源的狀況下,所能提供的單位時間服務能力是有限的。假如超過服務能力,通常會形成整個接口服務停頓,或者應用 Crash,或者帶來連鎖反應,將延遲傳遞給服務調用方形成整個系統的服務能力喪失。有必要在服務能力超限的狀況下 Fail Fast。安全
另外,根據排隊論,因爲 API 接口服務具備延遲隨着請求量提高迅速提高的特色,爲了保證 SLA 的低延遲,須要控制單位時間的請求量。這也是 Little’s law 所說的。
架構
因此,提供資源可以支撐的服務,將過載請求快速拋棄對整個系統架構的穩定性很是重要。這就要求在應用層實現 Rate limiting 限制。網站
Nginx 模塊ui
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { location /search/ { limit_req zone=one burst=5; }
配置解釋this
Google Guava 提供了一個 RateLimiter 實現spa
/** * Created by haoting.wang on 2017/3/13. */ public class RateLimiterDemo { //每秒處理一個 static RateLimiter rateLimiter = RateLimiter.create(1); private static int count = 10; static class Work implements Runnable{ int name; Work(int name){ this.name = name; } public void run() { rateLimiter.acquire(); System.out.println(name+"正在工做"); } } public static void main(String[] args){ for(int i = 0; i<count;i++){ new Thread(new RateLimiterDemo.Work(i)).start(); } } }
可是更好的限制方式是池, 線程池、數據庫鏈接池來限制訪問數量,將過載的請求放在隊列中,等待線程資源線程
這坑比啊 segmentfault,連個限流的標籤都沒,建個標籤還要聲望。mdzzcode