Nginx流量限制
Nginx流量限制可以有效防止DDOS攻擊,降低服務(wù)器負(fù)載,緩解硬件和網(wǎng)絡(luò)壓力,功能依賴于limit_req模塊,這個(gè)模塊現(xiàn)版本都是默認(rèn)集成的,所以不用單獨(dú)編譯安裝。
轉(zhuǎn)載資料:
關(guān)于limit_req和limit_conn的區(qū)別:https://www.cnblogs.com/zhoulujun/p/12183179.html
Nginx限制訪問速率和最大并發(fā)連接數(shù)模塊說明:https://www.cnblogs.com/wjoyxt/p/6128183.html
Nginx下limit_req模塊burst參數(shù)超詳細(xì)解析:https://blog.csdn.net/hellow__world/article/details/78658041
關(guān)于limit_req和limit_conn的區(qū)別
what is the difference between connection and request?
Nginx限流配置–limit_req和limit_conn (防范DDOS攻擊)
https://www.cnblogs.com/andrew-303/p/12272099.html
connection是連接,即常說的tcp連接,通過三次握手而建立的一個(gè)完整狀態(tài)機(jī)。建立一個(gè)連接,必須得要三次握手。
request是指請求,即http請求,tcp連接是有狀態(tài)的,而構(gòu)建在tcp之上的http卻是無狀態(tài)的協(xié)議
通過打開一個(gè)網(wǎng)頁,然后通過wareshark可以看到,一個(gè)連接建立后(即三次握手后),在這個(gè)連接斷開之前(即四次揮手之前),會有很多的http request,這就是他們的區(qū)別:即一個(gè)連接的生命周期中,會存在一個(gè)或者多個(gè)請求,這是為了加快效率,避免每次請求都要三次握手建立連接,現(xiàn)在的HTTP/1.1協(xié)議都支持這種特性,叫做keepalive。
這樣的配配置,表明以ip為key,來限制每個(gè)ip訪問lmit.html文件時(shí)候,最多只能有一個(gè)在線,否則其余的都要返回不可用。
這種情況就是一個(gè)靜止?fàn)顟B(tài)的計(jì)數(shù)可以實(shí)現(xiàn),而無關(guān)乎多長時(shí)間。
舉個(gè)例子,如果你的這個(gè)連接一直不釋放,即使你通過這一個(gè)連接發(fā)送出再多的request請求,只要我能夠應(yīng)付,那么我就幫你處理。
但是,如果你只需要處理2個(gè)請求,但是這兩個(gè)請求是分別用兩個(gè)連接同時(shí)發(fā)送過來的,那么,我就只能處理其中一個(gè),另外一個(gè)就不行。這就是他的區(qū)別。
limit_req_zone $binary_remtoe_addr zone=req_zone:1m rate=1r/s; #這里需要為共享內(nèi)存配置一個(gè)速率rate,limit_conn zone=req_zone;表明:對于每個(gè)ip來說,處理請求的速度不超過每秒1個(gè)請求。
可以看到這是個(gè)速度量(而上面的那個(gè)是數(shù)字量,速度和個(gè)數(shù)還是有直觀的區(qū)別的吧。。)
是同時(shí)發(fā)送出100個(gè)請求(不管是通過100個(gè)連接還是1個(gè)連接),只要你請求到底的速度超過每秒1個(gè),那么我就會拒絕你。
對于與 burst,推薦閱讀:Nginx下limit_req模塊burst參數(shù)超詳細(xì)解析 https://blog.csdn.net/hellow__world/article/details/78658041
這里把其總結(jié)摘錄如下:
limit_req zone=req_zone;
嚴(yán)格依照在limti_req_zone中配置的rate來處理請求
超過rate處理能力范圍的,直接drop
表現(xiàn)為對收到的請求無延時(shí)
limit_req zone=req_zone burst=5;
依照在limti_req_zone中配置的rate來處理請求
同時(shí)設(shè)置了一個(gè)大小為5的緩沖隊(duì)列,在緩沖隊(duì)列中的請求會等待慢慢處理
超過了burst緩沖隊(duì)列長度和rate處理能力的請求被直接丟棄
表現(xiàn)為對收到的請求有延時(shí)
limit_req zone=req_zone burst=5 nodelay;
依照在limti_req_zone中配置的rate來處理請求
同時(shí)設(shè)置了一個(gè)大小為5的緩沖隊(duì)列,當(dāng)請求到來時(shí),會爆發(fā)出一個(gè)峰值處理能力,對于峰值處理數(shù)量之外的請求,直接丟棄
在完成峰值請求之后,緩沖隊(duì)列不能再放入請求。如果rate=10r/m,且這段時(shí)間內(nèi)沒有請求再到來,則每6 s 緩沖隊(duì)列就能回復(fù)一個(gè)緩沖請求的能力,直到回復(fù)到能緩沖5個(gè)請求位置。
小伙伴對這個(gè)zone估計(jì)還是有一些疑問,有疑問可以在下面評論,大家一起討論,比如,有人可能會問,一個(gè)客服端占用5個(gè),那么327680只能容納65536個(gè)客服端,那么第65537個(gè)客服端就會返回503錯(cuò)誤
limit_conn_zone
語法:
Syntax: limit_conn_zone key zone=name:size;
Default: —
Context: http
看上面的語法,limit_conn_zone只能用在http段,例如:
對于關(guān)系:
key => $binary_remote_addr #二進(jìn)制的IP地址
name => addr #隨便取的一個(gè)名字,比如,你可以取成abc
size => 10m #空間大小,這里是10兆
一個(gè)二進(jìn)制的ip地址在32位機(jī)器上占用32個(gè)字節(jié),在64位機(jī)器上占用63個(gè)字節(jié),那么10M可以存放多少呢,計(jì)算一下,10x1024x1024/32 = 327680,意思就是可以存放326780個(gè)ip地址(32位),64位可以存放163840個(gè)ip
1、key:鍵,可以說是一個(gè)規(guī)則,就是對客戶端連接的一個(gè)標(biāo)識,比如上面用的是IP地址,比如我們可以用$query_string,例如:/index.php?mp=138944093953,那我們就可以根據(jù)mp的值來限制連接數(shù),更多的nginx內(nèi)置變量請查看http://nginx.org/en/docs/varindex.html
2、zone:共享內(nèi)存空間,作用:保存每個(gè)key對應(yīng)的連接數(shù)
3、size:共享內(nèi)存空間大小,如1M、10M、100K
當(dāng)共享內(nèi)存空間被耗盡,服務(wù)器將會對后續(xù)所有的請求返回 503 (Service Temporarily Unavailable) 錯(cuò)誤
limit_conn_log_level指令
Syntax: limit_conn_log_level info | notice | warn | error;
Default: limit_conn_log_level error;
Context: http, server, location
說明:當(dāng)達(dá)到最大限制連接數(shù)后,記錄日志的等級。
limit_conn_status指令
Syntax: limit_conn_status code;
Default: limit_conn_status 503;
Context: http, server, location
說明:當(dāng)超過限制后,返回的響應(yīng)狀態(tài)碼,默認(rèn)是503,現(xiàn)在你就知道上面為什么會返回503(Service Temporarily Unavailable)服務(wù)暫時(shí)不可用
例子:
1、同時(shí)限制ip和虛擬主機(jī)最大并發(fā)連接
http { limit_conn_zone binaryremoteaddrzone=perip:10m;limitconnzonebinaryremoteaddrzone=perip:10m;limitconnzoneserver_name zone=perserver:10m; server { location / { limit_conn perip 10; limit_conn perserver 1000; } } }最后放一個(gè)在公司遇到的需求,有個(gè)項(xiàng)目是請求服務(wù)器上的一個(gè)服務(wù)接口,但是程序請求的太頻繁了,導(dǎo)致服務(wù)這邊請求過快,被第三方偵測為惡意爬取而導(dǎo)致了封號。按說應(yīng)該修改一下程序,降低請求速率,但是恰巧開發(fā)程序的人聯(lián)系不到了,那只能下策,修改咱們Nginx代理的接口這邊的流量限制,從而達(dá)到降低請求頻率的目的。
Nginx修改的位置只有兩處
主配置文件:
虛擬服務(wù)器的配置文件:
location /xxx {limit_req zone=one burst=30 nodelay;proxy_pass http://127.0.0.1:8090;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}做好后寫個(gè)驗(yàn)證腳本
/bin/bash while : do echo 開始執(zhí)行調(diào)用 curl -s -w '%{http_code}' "http://xxx.xxx.cn/xxx/xxx echo 睡眠10秒后再次請求 sleep 10 done跑一下,因?yàn)樵蹅冊O(shè)定的是30秒接受一次請求,緩存池是5次,也就是說跑這個(gè)腳本時(shí)是跑到第7次時(shí)出現(xiàn)503返回值,然后每兩次503一次200的頻率,就驗(yàn)證成功了
總結(jié)
- 上一篇: 请输入密码登入
- 下一篇: Nginx--流量限制(最有用的功能之一