溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Nginx如何限流

發(fā)布時間:2021-12-13 09:49:44 來源:億速云 閱讀:193 作者:小新 欄目:大數(shù)據(jù)

這篇文章主要介紹了Nginx如何限流,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

1   漏桶和令牌桶算法的概念

漏桶算法(Leaky Bucket):主要目的是控制數(shù)據(jù)注入到網(wǎng)絡(luò)的速率,平滑網(wǎng)絡(luò)上的突發(fā)流量。漏桶算法提供了一種機(jī)制,通過它,突發(fā)流量可以被整形以便為網(wǎng)絡(luò)提供一個穩(wěn)定的流量。漏桶算法的示意圖如下圖所示,請求先進(jìn)入到漏桶里,漏桶以一定的速度出水,當(dāng)水請求過大會直接溢出,可以看出漏桶算法能強(qiáng)行限制數(shù)據(jù)的傳輸速率。

Nginx如何限流

令牌桶算法(Token Bucket):是網(wǎng)絡(luò)流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一種算法。典型情況下,令牌桶算法用來控制發(fā)送到網(wǎng)絡(luò)上的數(shù)據(jù)的數(shù)目,并允許突發(fā)數(shù)據(jù)的發(fā)送。令牌桶算法示意圖如下圖所示,大小固定的令牌桶可自行以恒定的速率源源不斷地產(chǎn)生令牌。如果令牌不被消耗,或者被消耗的速度小于產(chǎn)生的速度,令牌就會不斷地增多,直到把桶填滿。后面再產(chǎn)生的令牌就會從桶中溢出。最后桶中可以保存的最大令牌數(shù)永遠(yuǎn)不會超過桶的大小。

Nginx如何限流

2   兩種算法的區(qū)別

兩者主要區(qū)別在于“漏桶算法”能夠強(qiáng)行限制數(shù)據(jù)的傳輸速率,而“令牌桶算法”在能夠限制數(shù)據(jù)的平均傳輸速率外,還允許某種程度的突發(fā)傳輸。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允許突發(fā)地傳輸數(shù)據(jù)直到達(dá)到用戶配置的門限,所以它適合于具有突發(fā)特性的流量。

3  按請求速率限速

按請求速率限速是指限制IP發(fā)送請求的速率,超出指定速率后,Nginx將直接拒絕更多的請求。采用漏桶算法實現(xiàn)。下面從一些實驗數(shù)據(jù)上來深入的了解這個模塊,先簡單介紹一下該模塊的配置方式,如下圖所示(配置需要在Nginx配置和域名配置里面同時修改),使用limit_req_zone關(guān)鍵字,定義一個名為tip大小為10MB的共享內(nèi)存區(qū)域(zone),用來存放限速相關(guān)的統(tǒng)計信息,限速的key值為二進(jìn)制的IP地址($binary_remote_addr),限速上限(rate)為2r/s。

將上述規(guī)則應(yīng)用到/search目錄(單個IP的訪問速度被限制在了2請求/秒,超過這個限制的訪問將直接被Nginx拒絕)。burst和nodelay的作用稍后解釋。(zone=tip:10m表示會話空間的存儲大小為10m)。

Nginx如何限流

4   3個實驗案例

實驗1、討論2個請求在1s內(nèi)的執(zhí)行過程

修改配置下圖所示:

Nginx如何限流

我們使用ab工具模擬1s發(fā)送2個請求。

Nginx如何限流

只有一個請求成功了,查看了一下執(zhí)行時間:

Nginx如何限流

1ms內(nèi)完成了所有請求,考慮到每秒兩個請求可能是分時間段來來完成的,二分法做了大量延遲處理的嘗試,當(dāng)兩個請求之間的時延大于0.5s時第二個請求才會成功。

Nginx如何限流

結(jié)論:Nginx的限流統(tǒng)計是基于毫秒的,我們設(shè)置的速度是2r/s,轉(zhuǎn)換一下就是500ms內(nèi)單個IP只允許通過1個請求,從501ms開始才允許通過第二個請求。

Nginx如何限流

實驗2、burst允許緩存處理突發(fā)請求

如果短時間內(nèi)發(fā)送了大量請求,Nginx按照毫秒級精度統(tǒng)計,超出限制的請求直接拒絕。這在實際場景中未免過于苛刻,真實網(wǎng)絡(luò)環(huán)境中請求到來不是勻速的,很可能有請求“突發(fā)”的情況。Nginx考慮到了這種情況,可以通過burst關(guān)鍵字開啟對突發(fā)請求的緩存處理,而不是直接拒絕。(類似令牌桶算法)

修改Nginx配置如下:

Nginx如何限流

我們加入了burst=4,意思是每個key(此處是每個IP)最多允許4個突發(fā)請求的到來。使用ab工具發(fā)送6個請求,結(jié)果會怎樣呢?

Nginx如何限流

發(fā)送時間:

Nginx如何限流

執(zhí)行結(jié)果是請求全部被處理,加入緩沖隊列后,按照之前時間軸的規(guī)則 ,在0.001s、0.501s、1.001s、1.501s、2.001s、2.501s分別發(fā)送一個請求,與之前的有些偏差,理論上數(shù)據(jù)應(yīng)該是同時發(fā)送到ngnix,我們做了抓包統(tǒng)進(jìn)行驗證,可以觀察到6個請求分別開辟了6個端口進(jìn)行發(fā)送,只有當(dāng)?shù)谝粋€包三次握手完成,第二個包才開始發(fā)送,時間間隔500ms,這就驗證了ab工具確實是單個發(fā)送的。

Nginx如何限流

另外,理論上緩沖區(qū)之外的2個請求應(yīng)該只有一個是200,另外一個是503,緩沖區(qū)的4個請求是按照2r/s的速度依次處理,這里是由于ab工具本身的問題,在加入緩沖隊列后,發(fā)送時間由之前的1ms內(nèi)完成變成了2501ms完成,所以導(dǎo)致了請求都被處理掉,若是使用其他工具短時間內(nèi)發(fā)送6個請求,則只能成功5個。

Nginx如何限流

發(fā)送耗時2ms,完成處理時間2437ms,每個請求的處理時間。

Nginx如何限流

由于ngnix 500ms處理完第一個請求后,501ms才會處理第二個請求,所以5個請求(去掉503那個)耗時500ms*4+416ms=2416ms(本地實測,不同Nginx性能有所差異),或者使用ab工具并發(fā)來處理這些請求,也會有同樣的效果。

Nginx如何限流

我們再來觀察一下發(fā)送時間,所有的請求基本在10ms內(nèi)發(fā)起,這樣便導(dǎo)致了6個請求中,去掉第一個和緩沖區(qū)的4個,第二個被拒絕掉。

Nginx如何限流

實驗3、nodelay降低排隊時間

通過設(shè)置burst參數(shù),我們可以允許Nginx緩存處理一定程度的突發(fā),多余的請求可以先放到隊列里,慢慢處理,這起到了平滑流量的作用。但是如果隊列設(shè)置的比較大,請求排隊的時間就會比較長,這對用戶很不友好。nodelay參數(shù)允許請求在排隊的時候就立即被處理,也就是說只要請求能夠進(jìn)入burst隊列,就會立即被后臺worker處理。

延續(xù)實驗2的配置,我們加入nodelay選項:

Nginx如何限流

同樣發(fā)送6個請求發(fā)送時間:

Nginx如何限流

實驗結(jié)果如下圖所示:

Nginx如何限流

處理時間:

Nginx如何限流

與實驗2相比直觀上的效果就是Nginx同時出現(xiàn)6條日志,即6個請求是同時被處理的,而實驗2日志是逐條生成的,間隔0.5s,視覺上有卡頓。

雖然設(shè)置burst和nodelay能夠降低突發(fā)請求的處理時間,但是長期來看并不會提高吞吐量的上限,長期吞吐量的上限是由rate決定的,因為nodelay只能保證burst的請求被立即處理,加入了nodelay參數(shù)之后的限速算法還算是漏桶算法,當(dāng)令牌桶算法的token為耗盡時,由于它有一個請求隊列,所以會把接下來的請求緩存下來,緩存多少受限于隊列大小。假如server已經(jīng)過載,緩存隊列越來越長,即使過了很久請求被處理了,對用戶來說也沒什么價值了。所以當(dāng)token不夠用時,最明智的做法就是直接拒絕用戶的請求,即漏桶算法。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Nginx如何限流”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI