nginx限制請求之二:(ngx_http_limit_req_module)模塊


相關文章:

高可用服務設計之二:Rate limiting 限流與降級

nginx限制請求之一:(ngx_http_limit_conn_module)模塊

nginx限制請求之二:(ngx_http_limit_req_module)模塊

nginx限制請求之三:Nginx+Lua+Redis 對請求進行限制

nginx限制請求之四:目錄進行IP限制

上一篇文章主要寫nginx限制連接數ngx_http_limit_conn_module 模塊的作用及使用方法,下面來寫ngx_http_limit_req_module模塊的作用及使用。

通過ngx_http_limit_req_module 模塊可以通過定義的鍵值來限制請求處理的頻率。特別的,可以限制來自單個IP地址的請求處理頻率。 限制的方法如同漏斗,每秒固定處理請求數,推遲過多請求。例如,單客戶端IP的每秒請求數。實現的原理是使用“漏桶”原理(限流算法之漏桶算法、令牌桶算法)。

該模塊提供了兩個配置參數,limit_req_zone 和 limit_req ,其中 limit_req_zone 只能配置在 http{} 段,而 limit_req 則可以配置於http{},server{},location{} 區段中。


第三方模塊編譯安裝參數:

這里寫圖片描述


一、limit_req_zone

語法:limit_req_zone $variable zone=name:size rate=rate; 
配置段:http

該指令設置一塊共享內存限制域用來保存鍵值的狀態參數。特別是保存了當前超出請求的數量。鍵的值就是指定的變量(控制不被計算)。如:

這里寫圖片描述

注釋: 
使用$binary_remote_addr變量,可以將每條狀態記錄的大小減少到64個字節,這樣1M的內存可以保存大約1萬6千個64字節的記錄

如果限制域的存儲空間耗盡了,對於后續所有請求,服務器都會返回503(Service Temporarily Unavailable)錯誤

速度可以設置為每秒處理請求數和每分鍾處理請求數,其值必須是整數,所以如果你需要每秒處理少於1個的請求,2秒處理一個請求,可以使用30r/m


二、limit_req

語法: limit_req zone=name burst=number [nodelay]; 
配置段:http,server,location

設置對應的共享內存限制域和允許被處理的最大請求數閥值。如果請求的頻率超過了限制域配置的值,請求處理會被延遲,所以所有的請求都是以定義的頻率被處理的。超過頻率限制的請求會被延遲,直到被延遲的請求數超過了定義的閥值,這時,這個請求會被終止,並返回503(Service Tempporarily Unavailable)錯誤,這個閥值的默認值為0,如:

限制頻率每秒不超過一個請求,同時允許超過頻率限制的請求數不多於100個;如果不希望超過的請求被延遲,可以用nodelay參數。

這里寫圖片描述


三、配置使用示例

limit_req_zone $binary_remote_addr zone=showjoy_req:20m rate=1r/s; 
主要是用來定義變量,空間名稱,以及共享內存大小。

limit_req zone=showjoy_req burst=100 nodelay; 
主要是用來使用前面定義的空間,定義請求頻率限制,使用nodelay則表示不希望超過的請求被延遲。

這里寫圖片描述

可能要對某些IP不做限制,需要使用到白名單。

模塊地址:https://yunpan.cn/cqSKP6BrJ2AeT 訪問密碼 4f50

 

關於limit_req和limit_conn的區別

1,首先,limit_req和limit_conn兩個模塊都是為了來限流的,但是兩者不在一個層面,為了搞清楚這個,必須先要弄清楚request和connection的區別,因為在很多情況下,我們把他們混淆了。

so, what is the difference  between connection and request? 

2, connection是連接,即常說的tcp連接,通過三次握手而建立的一個完整狀態機。建立一個連接,必須得要三次握手。

request是指請求,即http請求,(注意,tcp連接是有狀態的,而構建在tcp之上的http卻是無狀態的協議)。

通過打開一個網頁,然后通過wareshark可以看到,一個連接建立后(即三次握手后),在這個連接斷開之前(即四次揮手之前),會有很多的http request,這就是他們的區別:即一個連接的生命周期中,會存在一個或者多個請求,這是為了加快效率,避免每次請求都要三次握手建立連接,現在的HTTP/1.1協議都支持這種特性,叫做keepalive。

好了現在知道區別了。

3,那么在Nginx中,對於連接限制模塊:limit_conn_module來看:

limit_conn_zone $binanry_remote_addr zone=conn_zone:1m;
locoation /limit.html {
    limit_conn conn_zone 1;
}

這樣的配配置,表明以ip為key,來限制每個ip訪問lmit.html文件時候,最多只能有一個在線,否則其余的都要返回不可用。

這種情況就是一個靜止狀態的計數可以實現,而無關乎多長時間。

舉個例子,如果你的這個連接一直不釋放,即使你通過這一個連接發送出再多的request請求,只要我能夠應付,那么我就幫你處理。但是,如果你只需要處理2個請求,但是這兩個請求是分別用兩個連接同時發送過來的,那么,我就只能處理其中一個,另外一個就不行。這就是他的區別。

可以用ab命令來測試:

ab -n100 -c100 -k http://yoursit/limit.html

注意:ab命令的-n -c都是指的發送多少請求,即-n一共發送多少請求,-c同時發送多少請求,他並不關心需要多少連接來發送,默認情況下是每個請求都建立一個連接來發送。

上面這個命令,由於默認是一個連接發送一個請求,那么這將會同時建立100個連接,而這樣的話,就會導致限制超過(最多只能一個連接for一個ip)。99個請求都會失敗。

而如果你只開一個連接:

ab -n100 -c100 -k http://yousit/limt.html

這里的-k選秀就是表示keepalive,只開一個連接來發送這100個請求,即使是同時發送,那么server也不會認為你超過了,因為在一個時間你只是建立一個連接,這樣這100個請求都會干凈利落的處理完成。

3,再看limit_req_module 

limit_req_zone $binary_remtoe_addr zone=req_zone:1m rate=1r/s;
location /limit.html{
    limit_conn zone=req_zone;
}

注意和上面的區別:這里需要為共享內存配置一個速率rate

表明:對於每個ip來說,處理請求的速度不超過每秒1個請求。

可以看到這是個速度量(而上面的那個是數字量,速度和個數還是有直觀的區別的吧。。)

那么這時候 :

ab -n100 -c100 http://yoursit/limit.html 

ab -n100 -c100 -k http://yousit/limt.html

的區別就不是那么明顯了,因為這總是同時發送出100個請求(不管是通過100個連接還是1個連接),只要你請求到底的速度超過每秒1個,那么我就會拒絕你。

附加:https://forum.linode.com/viewtopic.php?t=8064%3E


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM