相關文章:php
《高可用服務設計之二:Rate limiting 限流與降級》html
《nginx限制請求之一:(ngx_http_limit_conn_module)模塊》node
《nginx限制請求之二:(ngx_http_limit_req_module)模塊》nginx
《nginx限制請求之三:Nginx+Lua+Redis 對請求進行限制》算法
《nginx限制請求之四:目錄進行IP限制》服務器
上一篇文章主要寫nginx限制鏈接數ngx_http_limit_conn_module 模塊的做用及使用方法,下面來寫ngx_http_limit_req_module模塊的做用及使用。tcp
經過ngx_http_limit_req_module 模塊能夠經過定義的鍵值來限制請求處理的頻率。特別的,能夠限制來自單個IP地址的請求處理頻率。 限制的方法如同漏斗,每秒固定處理請求數,推遲過多請求。例如,單客戶端IP的每秒請求數。實現的原理是使用「漏桶」原理(限流算法之漏桶算法、令牌桶算法)。post
該模塊提供了兩個配置參數,limit_req_zone 和 limit_req ,其中 limit_req_zone 只能配置在 http{} 段,而 limit_req 則能夠配置於http{},server{},location{} 區段中。測試
語法:limit_req_zone $variable zone=name:size rate=rate;
配置段:httpurl
該指令設置一塊共享內存限制域用來保存鍵值的狀態參數。特別是保存了當前超出請求的數量。鍵的值就是指定的變量(控制不被計算)。如:
註釋:
使用$binary_remote_addr變量,能夠將每條狀態記錄的大小減小到64個字節,這樣1M的內存能夠保存大約1萬6千個64字節的記錄
若是限制域的存儲空間耗盡了,對於後續全部請求,服務器都會返回503(Service Temporarily Unavailable)錯誤
速度能夠設置爲每秒處理請求數和每分鐘處理請求數,其值必須是整數,因此若是你須要每秒處理少於1個的請求,2秒處理一個請求,可使用30r/m
語法: 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
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