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

相關文章: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{} 區段中。測試


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

這裏寫圖片描述


1、limit_req_zone

語法: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


2、limit_req

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

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

限制頻率每秒不超過一個請求,同時容許超過頻率限制的請求數很少於100個;若是不但願超過的請求被延遲,能夠用nodelay參數。

這裏寫圖片描述


3、配置使用示例

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

相關文章
相關標籤/搜索