限流指的是限制系統的併發訪問策略,保證系統能夠接受部分使用者的請求,而對於超過流量控制的請求,系統會拒絕請求。限流是為了保護系統不會被過載的流量打垮,其通常做在服務入口層如閘道器,它可以對整個系統,某個服務,某個介面,某個ip或者某個使用者做限制。
常用的限流演算法有固定視窗,滑動視窗,漏桶演算法與令牌桶演算法。
固定視窗指的是在固定的時間視窗內限制請求的數量,超過數量的請求直接拒絕。比如限制1分鐘內只能接收1w筆請求,超過1w筆的請求直接拒絕請求,等到下乙個一分鐘重新開始計數。從固定視窗的演算法中可以看出,在上面的例子中,如果請求全部集中在最後的1秒中,下乙個一分鐘的請求又全部集中在前1秒中,那麼在時間視窗的交界處,qps達到2w/s,從而導致臨界區內超過了限流的閾值。
由於固定視窗不能控制臨界區內的請求數量,為此引入了滑動視窗,滑動視窗是將固定視窗範圍繼續劃分出多個小視窗,比如上個例子中,將1分鐘按1秒的間隔劃分為60個小視窗,每個小視窗維護乙個計數,滑動視窗將限制任意連續的60個小視窗的請求之和不超過1w。滑動視窗很好的解決了固定視窗演算法在兩個臨界的視窗的請求過於集中的問題,但是還是不能平滑請求,因為乙個時間視窗內的請求,可能全部聚集於某個小視窗內,同時還增加了演算法的複雜度。
為此在實際專案中,我們很少基於時間視窗的限流演算法,一般使用漏桶演算法與令牌桶演算法。
漏桶演算法就像是在流量的生產者與消費者之間增加乙個漏桶,漏桶以每秒固定的速率流出流量,當漏桶滿了後,生產者將不能在往漏桶中新增請求。漏桶演算法一般通過乙個有界的佇列實現,當佇列滿了就不能往佇列裡面新增請求,從而實現將請求平滑的到達消費者。它能夠很好的平滑請求,但是由於引入了佇列快取請求,增加了請求的響應時間,為此我們一般更推薦使用令牌桶演算法。
令牌桶演算法的基本思想是
1、如果我們要在1秒內限制n個請求,那麼可以每隔1/n秒往桶裡面放入乙個令牌;
2、當有請求要處理的時候,就往桶裡取乙個令牌,同時減少令牌桶中令牌的數量;如果取不到令牌,則拒絕請求;
3、令牌桶的大小也需要有上限的,當令牌的個數超過n個,就不在往桶裡面增加令牌。
令牌桶演算法也可以很好的平滑請求,同時允許一定的突發流量。為此我們一般選擇令牌桶演算法來實現限流。
如果需要實現分布式限流我們一般使用redis來儲存令牌,但是如果每次請求都從redis獲取令牌,那麼每個請求都會增加一次網路開銷,為此在高併發的場景下,我們一般先預取一定數量的令牌。
在實際的環境中我們一般很難確定乙個準確的閾值,為此我們需要在配置中心中新增配置選項,以動態調整限流閾值。同時定期的壓測需要限流的系統與微服務,然後修改配置中心中的閾值。
高併發系統設計 限流
前面學習過的熔斷和降級都是通過暫時關閉某些非核心服務或者元件來保護核心系統的可用性。但是並不是所有的場景下都可以使用熔斷降級的策略,例如當核心服務產生比較大的影響時,總不能把核心服務進行熔斷與降級,些時一般採用限流方案來進行保護。限流指的是通過限制到達系統的併發請求數量,保證系統能夠正常響應部分使用...
Java高併發系統的限流策略
在大資料量高併發訪問時,經常會出現服務或介面面對暴漲的請求而不可用的情況,甚至引發連鎖反映導致整個系統崩潰。此時你需要使用的技術手段之一就是限流,當請求達到一定的併發數或速率,就進行等待 排隊 降級 拒絕服務等。在開發高併發系統時有三把利器用來保護系統 快取 降級和限流。快取比較好理解,在大型高併發...
TCP 協議中的流量控制
協議 流量控制 滑動視窗 nagle tcp 協議中的流量控制 tcp協議上的網路協議特別多1 互動資料型別,例如 telet ssh 這種型別的協議在大多數情況下只是做小流量的資料交換,比如說按一下鍵盤,回顯一些文字等等。2 資料成塊型別,例如 ftp,這種型別的協議要求 tcp能盡量的運載資料,...