轉載於:http://storysky.blog.51cto.com/628458/642970/
nginx 上有兩個限制連接的模塊一個是 limit_zone 另一個是 limie_req_zone,兩個都可以限制連接,但具體有什么不同呢?
下面是 nginx 官網上給的解釋
limit_req_zone
Limit frequency of connections from a client.
This module allows you to limit the number of requests for a given session, or as a special case, with one address.
Restriction done using leaky bucket.
limit_zone
Limit simultaneous connections from a client.
This module makes it possible to limit the number of simultaneous connections for the assigned session or as a special case, from one address.
按照字面的理解,lit_req_zone的功能是通過 令牌桶原理來限制 用戶的連接頻率,(這個模塊允許你去限制單個地址 指定會話或特殊需要 的請求數 )
而 limit_zone 功能是限制一個客戶端的並發連接數。(這個模塊可以限制單個地址 的指定會話 或者特殊情況的並發連接數)
一個是限制並發連接一個是限制連接頻率,表面上似乎看不出來有什么區別,那就看看實際的效果吧~~~
在我的測試機上面加上這兩個參數下面是我的部分配置文件
http{
limit_zone one $binary_remote_addr 10m;
#limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
server
{
......
limit_conn one 1;
#limit_req zone=req_one burst=120;
......
}
}
解釋一下 limit_zone one $binary_remote_addr 10m;
這里的 one 是聲明一個 limit_zone 的名字,$binary_remote_addr是替代 $remore_addr 的變量,10m 是會話狀態儲存的空間
limit_conn one 1 ,限制客戶端並發連接數量為1
先測試 limit_zone 這個模塊
我找一台機器 用ab 來測試一下 命令格式為
ab -c 100 -t 10 http://192.168.6.26/test.php
test.php 內容是phpinfo
看看日志里的訪問
看來也不一定能限制的住1秒鍾1個並發連接,(有網友跟我說這是因為測試的文件本身太小了才會這樣,有時間一定測試一下),從日志里面可以看得出來 除了幾個200以外其他的基本都是503,多數並發訪問都被503了。
我又用ab多運行了一會兒,發現另一種情況
似乎隨着數量的增多效果也會發生一些變化,並不是完全達到模塊說明中的效果
看看當前的tcp連接數
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 29
FIN_WAIT1 152
FIN_WAIT2 2
ESTABLISHED 26
SYN_RECV 16
這次測試下 limit_req_zone,配置文件稍微改動一下
http{
#limit_zone one $binary_remote_addr 10m;
limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
server
{
......
#limit_conn one 1;
limit_req zone=req_one burst=120;
......
}
}
restart 一下 nginx
簡單說明一下, rate=1r/s 的意思是每個地址每秒只能請求一次,也就是說根據令牌桶(經過網友冰冰的指正應該是漏桶原理)原理 burst=120 一共有120塊令牌,並且每秒鍾只新增1塊令牌,
120塊令牌發完后 多出來的那些請求就會返回503
測試一下
ab -c 100 -t 10 http://192.168.6.26/test.php
看看這時候的訪問日志
確實是每秒請求一次,那多測試一會兒呢?把時間從10秒增加到30秒
這個時候應該是120 已經不夠用了,出現很多503,還有兩種情況會出現,請看圖
這種情況很像是 在隊列里的一些請求得不到響應而超時了,但我不確定是不是這種情況。
客戶端自己等不及斷開了,返回499
看看當前的tcp連接數
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 51
FIN_WAIT1 5
ESTABLISHED 155
SYN_RECV 12
雖然這樣會讓nginx 一秒鍾只處理一個請求,但是仍然會有很多還在隊列里面等待處理,這樣也會占用很多tcp連接,從上面那條命令的結果中就能看得出來。
如果這樣呢
limit_req zone=req_one burst=120 nodelay;
加上 nodelay之后超過 burst大小的請求就會直接 返回503,如圖
也是每秒處理1個請求,但多出來的請求沒有象剛才那樣等待處理,而是直接返回503。
當前的tcp連接
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 30
FIN_WAIT1 15
SYN_SENT 7
FIN_WAIT2 1
ESTABLISHED 40
SYN_RECV 37
已連接的數量比上面的少了一些
通過這次測試我發現 這兩種模塊都不能做到絕對的限制,但的確已經起到了很大的減少並發和限制連接的作用,在生產環境中具體用哪種或者需要兩種在一起使用就要看各自的需求了。
測試就到這里,如果文章里有不對的地方請大家及時指正,謝謝