通俗的說,流量控制就是控制用戶請求的策略,主要包括:權限、限流、流量調度。
權限上壹篇已經講過了,這壹篇講限流,下壹篇講流量調度。
限流是指限制用戶調用的頻率(QPS/QPM)或者次數。
流量限制,站在用戶或者運營的角度看,最直觀能感受到的作用是——收費
各大主流開放平臺的對外API,壹般都有壹些免費的額度,可以供個人測試用,壹旦想大規模調用,就需要付費購買更大的額度(頻率、次數),根據調用次數或者頻率進行收費。壹旦超過擁有的額度,就會被限制調用。
其實這才是限流最大的用處,只是用戶或者運營同學無感,所以不太被大多數人了解。
網關後面是各個服務,各個服務的接口通過網關透出去給用戶調用。理論上說,用戶的流量是不可預知的,隨時可能來壹波,壹旦流量的峰值超過了服務的承載能力,服務就掛了,比如有大新聞發生時的某浪微博,比如前些年的12306.
所以, 網關必須保證,放過去到達後端服務的流量壹定不可以超過服務可以承載的上限 。這個上限,是網關和各個服務協商出來的。
由簡到難,限流可以 分為單機限流、單集群限流、全集群限流 。
這裏不討論具體的如漏桶、令牌桶等限流算法,只說概念和思想。
單機限流的思想很簡單,就是每個機器的限流值 x 機器數量 = 總的限流值。
舉個例子,A用戶的QPS限制是100,網關部署了10臺機器,那麽,每臺機器限制10QPS就可以了。
先說好處,這種方法實現起來非常簡單,每臺機器在本地內存計算qps就可以了,超過閾值就拒流。
不過單機限流的缺陷也十分明顯,主要體現在兩點:
? 當網關部署的機器數量發生變化時,每臺機器的限流值需要根據機器數調整。現實中,因為擴容、縮容、機器宕機等原因,機器數的變化是常有的事。
? 單機限流的前提是,每臺網關承載的用戶的流量是平均的,但是事實上,在某些時間,用戶的流量並不是完全平均分布在每臺機器上的。
舉個例子:
10臺機器,每臺限qps10,其中3臺每臺實際qps是15,因為超限導致用戶流量被拒。其余7臺每臺qps是7。這樣用戶總的qps = 15 * 3 + 7 * 7 = 94. 用戶qps並沒有超限,但是卻有壹部分流量被拒了,這樣就很有問題。
實際上,單臺限流的閾值也會設置的稍微大壹些,以抵消流量不均的問題。
因為上面的問題, 單機限流通常作為壹種兜底的備用手段,大多數時候用的還是集群限流 。
先來看壹個示意圖:
相比單機限流,集群限流的計數工作上移到redis集群內進行,解決了單機限流的缺陷。
但是集群限流也不是完美的,因為引入了redis,那麽,當網關和redis之間的網絡抖動、redis本身故障時,集群限流就失效了,這時候,還是得依靠單機限流進行兜底。
也就是說, 集群限流 + 單機限流配合,才是壹個比穩妥的方案 。
接下來我們來思考這樣壹個問題:大型網關壹般都是多機房、多地域部署的,當然,後端的服務也是多機房、多地域部署的,在保護服務這壹點來說,集群限流是夠用了。但是對用戶來說,還是有壹些問題:
比如,用戶購買的QPS上限是30,我們的網關部署在中國北、中、南三個地域,那麽這30QPS怎麽分配呢?
平均肯定不行,用戶的流量可能是明顯不均衡的,比如用戶的業務主要集中在中國北方,那麽用戶的流量大部分都會進入北方的網關,網關如果限制QPS為10的話,用戶肯定來投訴。
那每個地域都限制為30行不行?也不行,如果用戶的流量比較均勻的分布在各個地域,那麽用戶購買了30QPS,實際上可能使用了90QPS,這太虧了。
按照解決單機限流流量不均的思路,搞壹個公***的redis集群來計數行不行?
也不行,受限於信號傳播速度和天朝的廣闊疆域,每個流量都計數,肯定不現實,rt太高會導致限流失去意義,帶寬成本也會變得極其昂貴,對redis的規格要求也會很高。總之,很貴還解決不了問題。
有壹種巧妙的解決辦法是:本地集群階梯計數 + 全集群檢查。
還是剛才的例子:
限流閾值時90,那麽三個地域各自計數,當本地域的數值達到30時,去其他兩個地域取壹次對方當前的計數值,三個地域的計數值加起來,如果超了,告訴另外兩個地域超了,開始拒流。如果沒超,本地QPS每上漲10,重復壹次上述的動作。
這樣就能有效的減少與redis的交互次數,同時實現了全地域真·集群限流。
當然,這種全地域集群限流,因為rt和階梯計數間隔的存在,壹定是不準的,但是,比單集群限流還是好很多。
當某個用戶流量特別大的時候,redis計數就會遇到典型的熱點key問題,導致redis集群單節點壓力過大, 有兩種辦法可以解決這個問題:打散和抽樣。
打散是指,把熱點key加壹些後綴,使其變成多個key,從而hash到不通的redis節點上,均攤壓力。
比如熱點key是abcd,那麽打散後,key變成了abcd1、abcd2、abcd3、abcd4。技術時,輪流加1、2、3、4的後綴就可以了。
抽樣是指,針對熱點key,不是每個每個請求到來時都進行計數,而是進行壹個抽樣,比如每10個請求記壹次數,這樣redis的壓力就會降低到十分之壹。
說著把流量調度的也說完了哈哈,那下壹篇再說說監控好了,順便推壹下我現在在用的國產網關:GOKU,來自Eolinker。我覺得比KONG好用,感興趣的同學可以自行去了解壹下。
www.eolinker.com