服務端流量控制的可行性方案

ForestXie發表於2017-06-26

服務端流量控制的可行性方案

今天這個話題,我相信對於做網際網路業務的朋友不會陌生,特別是電商或者互金領域。一碰到做大規模促銷活動,訪問量會有十倍乃至百倍的增加,比如現在正在做的618。做技術的童鞋都知道,每次在做大型活動前,我們都會整備物資,查漏補缺,拉標語打口號,各種活動演練,期待打一個大勝仗。但是實際上,除了‘鵝貓狗餓’這樣的大廠,其他小廠的軟硬體都是容易吃緊的。那麼真遇到流量吃不消了,就要考慮流量控制了,硬撐的結果,只會帶來更大的系統性風險。


什麼是流量控制?


流量控制就是監控當前系統的流量,如果超過預設的值或者當前系統的最大承受能力,則需要拒絕掉部分請求,以實現對系統的保護。最大承受能力的值來源於平時的壓力或者效能測試的結果。


流量控制的策略


流量控制一般有兩種策略方案:

1. 基於流量閾值的流控:流量閾值是每臺主機的流量上限,流量超過該閾值主機將進入不穩定狀態。閾值提前進行設定,如果主機當前流量超過閾值,則拒絕掉一部分流量,使得實際被處理流量始終低於閾值。

基於閾值的流控是最常見的一種方案,大多數的流控也是基於此,閾值一般通過壓力測試確定。但是需要提前設定閾值,而且由於現在的系統多采用分散式的方案,需要有同步的機制,保證閾值能有效的同步。


2. 基於主機狀態的流控:每個接受每個請求之前先判斷當前主機狀態,如果主機狀況不佳,則拒絕當前請求。基於主機狀態的流控的好處是省去了人為控制,不過難點在於需要制定一個穩定性的標準。而且還需要大量的實驗來證明標準是否足夠全面,否則不會觸發流量控制。所以,如果對服務的狀態沒有足夠的瞭解下,設定閾值的流控是最穩妥的辦法。


流量控制的執行方案


按照服務端外部和內部的流量進行分類,有兩種執行方案:


1. 外部HTTP訪問流控

通過Nginx或者Tengine反向代理實現,基於各種策略進行流量控制。


例如,

(1). 限制每秒請求數

涉及模組:ngx_http_limit_req_module

通過漏桶原理來限制單位時間內的請求數,一旦單位時間內請求數超過限制,就會返回 503 錯誤。

範例:

http {    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
    ...
    server {
        ...
        location  ~ \.php$ {            limit_req zone=one burst=5 nodelay;  
               }
           }
     }複製程式碼


(2).白名單設定

http_limit_conn 和 http_limit_req 模組限制了單 IP 單位時間內的連線和請求數,但是如果 Nginx 前面有 lvs 或者 haproxy 之類的負載均衡或者反向代理,nginx 獲取的都是來自負載均衡的連線或請求,這時不應該限制負載均衡的連線和請求,就需要 geo 和 map 模組設定白名單:

geo $whiteiplist  {
        default 1;        10.11.15.1610;
    }
map $whiteiplist$limit {        1$binary_remote_addr;        0"";
    }limit_req_zone $limit zone=one:10m rate=10r/s;limit_conn_zone $limit zone=addr:10m;


複製程式碼

2. 內部流量控制

對於內部服務的流量控制,可以考慮系統資源的使用情況,當系統資源成為瓶頸時,內部服務框架需要對消費者做限流,啟動流控保護機制。對於內部流控檢測的資源包括但不侷限於以下系統:


CPU使用率。

記憶體使用率(對於Java,對應於JVM記憶體使用率)。

佇列積壓率。


當我們有明確的指標後,我們就需要制定對應的級別。不同級別拒掉的訊息比例不同,這取決於資源的負載使用情況。例如當發生一級流控時,拒絕掉1/4的訊息;發生二級流控時,拒絕掉1/2訊息;發生三級流控時,所有的訊息都被流控掉。

不同的級別有不同的流控閾值,系統上線後會提供預設的流控閾值,不同流控因子的流控閾值不同,業務上線之後通常會根據現場的實際情況做閾值調優,因此流控閾值需要支援線上修改和動態生效。

Dubbo服務框架提供服務呼叫入口的攔截點和切面介面,由業務實現自定義流控。也可以提供基礎的流控框架,供業務實現流控條件判斷、流控執行策略等,簡化業務的定製工作量。


最後,講個人的經驗提示:當因為流控而拒絕請求時,務必在返回的資料中帶上一個友好的提示資訊,一方面能讓終端使用者感覺更友好,另外一方面,從技術端,我們也能明確使用者之所以不能正常訪問,是因為流控的原因,而不是客戶端或者服務端的BUG,這是一個很大的坑。


掃描二維碼或手動搜尋微信公眾號【架構棧】: ForestNotes

歡迎轉載,帶上以下二維碼即可

服務端流量控制的可行性方案


相關文章