8.Nginx的請求限制( limit_conn_zone、 limit_conn古瓤、limit_req_zone止剖、limit_req zone)

Nginx的請求限制

在配置nginx的過程中我們需要考慮受到攻擊或惡意請求的情況,比如單用戶惡意發(fā)起大量請求落君,這時(shí)Nginx的請求限制可以幫助我們對(duì)其進(jìn)行限制穿香。

連接頻率限制 : limit_conn_module

請求頻率限制 : limit_req_module

理解:連接頻率限制和請求頻率限制都可以實(shí)現(xiàn)Nginx的請求限制 , 但是他們的實(shí)現(xiàn)原理是不一樣的 , 區(qū)別就在于連接和請求上 , http協(xié)議的鏈接與請求 , http協(xié)議是建立在tcp協(xié)議之上的,要完成一次http的請求,先要進(jìn)行tcp的3次握手建立http的連接 , 然后才進(jìn)行http的request和response(請求和響應(yīng)) , 現(xiàn)在http1.1以上的版本已經(jīng)可以實(shí)現(xiàn)一次建立http的連接進(jìn)行多次的http的request和response(請求和響應(yīng)) ,最后客戶端和服務(wù)端不斷的來發(fā)送FIN包和ACK包來保持HTTP的連接 。

如果面對(duì)搶購和秒殺需求來限制 , 個(gè)人覺得連接頻率限制和請求頻率限制應(yīng)該配合使用 , 使用連接頻率限制同一IP同時(shí)只能有3個(gè)連接, 再使用請求頻率限制對(duì)于同一ip的請求绎速,限制平均速率為5個(gè)請求/秒 , 這樣是不是比單獨(dú)只使用一種限制要好很多?

比如只使用連接頻率限制 , 由于一次建立http的連接可以進(jìn)行多次的請求和響應(yīng) , 我們無法精確的限制同一ip同時(shí)發(fā)起多少次的http請求 ;

比如只使用請求頻率限制 , 可以精確的限制同一ip1秒只能發(fā)起5次的http請求 , 假如同一ip1秒內(nèi)發(fā)起了100000次請求 , 雖然限制了只有5次成功響應(yīng) , 但是其他的99995次的請求TCP握手建立http連接是不是會(huì)消耗服務(wù)器資源?

所以,個(gè)人覺得連接頻率限制和請求頻率限制應(yīng)該配合使用!


HTTP協(xié)議的連接與請求

HTTP請求建立在一次TCP連接基礎(chǔ)上

一次TCP連接至少產(chǎn)生一次HTTP請求


連接限制

ngx_http_limit_conn_module模塊用于限制每個(gè)定義鍵的連接數(shù)皮获,特別是來自單個(gè)IP地址的連接數(shù)。

配置示例

http {

????...

? ?#對(duì)單個(gè)ip纹冤、單個(gè)會(huì)話同時(shí)存在的連接數(shù)的限制洒宝。這里定義一個(gè)存儲(chǔ)區(qū)conn_zone,conn_zone的容量是1m萌京,該存儲(chǔ)區(qū)針對(duì)于變量$binary_remote_add生效雁歌,這里是針對(duì)單個(gè)IP生效。該模塊只是一個(gè)定義知残,配置在http配置段靠瞎,需要配合limit_conn指令使用才生效,?limit_conn one 1表示該location段使用conn_zone定義的?limit_conn_zone?,對(duì)單個(gè)IP限制同時(shí)存在一個(gè)連接较坛。

? ? limit_conn_zone $binary_remote_addr zone=conn_zone:1m;

? ? server {

????????????location / {

? ? ? ? ? ? ? ? ? ? limit_conn conn_zone 1;

? ????????? }

}

做個(gè)演示:

未開啟連接限制時(shí)做個(gè)壓力測試 (不懂a(chǎn)b的可以看看https://www.cnblogs.com/TingJie/articles/4974885.html這個(gè)文章 , 很簡單明了)

ab -n 10000 -c 1000 http://192.168.58.100/index.html?

Complete requests:? ? ? 10000

Failed requests:? ? ? ? 78

這里模擬了10萬個(gè)請求 , 1000個(gè)并發(fā) , 78個(gè)請求失敗,打開nginx的錯(cuò)誤日志查看都是打開文件失敗的錯(cuò)誤 ( open() "/usr/share/nginx/html/50x.html" failed (24: Too many open files))! 想象一下 , 如果我們是一個(gè)商城程序的API接口 , 正常情況下 , 同一個(gè)IP下10萬個(gè)請求1000個(gè)并發(fā) , 算不算惡意攻擊?那么就需要做一下連接限制了噻 , 具體怎么限制根絕具體的邏輯去處理 , 我們這里簡單的限制一下(啟用配置示例的連接限制)再次做個(gè)壓力測試:

ab -n 10000 -c 1000 http://192.168.58.100/index.html?

Complete requests:? ? ? 100000

Failed requests:? ? ? ? 43616

開啟連接限制對(duì)單個(gè)IP限制同時(shí)只能存在一個(gè)連接,這里模擬了10萬個(gè)請求 , 1000個(gè)并發(fā) , 43616個(gè)請求失敗,打開nginx的錯(cuò)誤日志查看下錯(cuò)誤全是連接限制的作用(limiting connections by zone "conn_zone") ,?我們知道"現(xiàn)在http1.1以上的版本已經(jīng)可以實(shí)現(xiàn)一次建立http的連接進(jìn)行多次的http的request和response(請求和響應(yīng))?" , 大家想想 , 如果我們需要做一個(gè)搶購和秒殺 , 是不是需要對(duì)單個(gè)搶購和秒殺限制連接單個(gè)IP同時(shí)只能存在一個(gè)或者多個(gè)連接的限制?不然人家寫個(gè)腳本程序運(yùn)行在十臺(tái)八臺(tái)的機(jī)器上瘋狂的請求怎么辦?當(dāng)然這只是一個(gè)比較簡單的應(yīng)用場景 , 更多的還是需要自己思考與摸索.


請求限制

ngx_http_limit_req_module模塊用于限制請求的處理速率印蔗,特別是單一的IP地址的請求的處理速率扒最。使用“漏桶”方法進(jìn)行限制丑勤。

配置示例

http {

????...

? ?#$binary_remote_addr表示的是客戶端的地址,zone=req_zone:1m代表的是開辟了一個(gè)名為req_zone的1M的空間,1M的空間可以存儲(chǔ)多少個(gè)$binary_remote_addr這里不解釋了 , Nginx官網(wǎng)文檔介紹的相當(dāng)清除 , 速率rate=1r/s代表的是每秒1個(gè) , 所以這里定義的配置代表:對(duì)于同一ip的請求,限制平均速率為1個(gè)請求/秒吧趣。

? ? limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;

????server {

? ? ? ? ? ? ...

? ? ????????location / {

? ? ? ????????????? root? /usr/share/nginx/html;

? ? ? ????????????? index? index.html index.htm;

? ? ? ? ? ? ? ? ? ? #請求限制 : 對(duì)于符合名為req_zone的limit_req_zone 配置(對(duì)于同一ip的請求法竞,限制平均速率為1個(gè)請求/秒) ,?超過部分進(jìn)行延遲處理,若超過3個(gè)請求/秒强挫,丟棄超過部分岔霸。

????????????????????#limit_req zone=req_zone burst=3 nodelay;

? ? ? ? ? ? ? ? ? ? #請求限制 :?對(duì)于符合名為req_zone的limit_req_zone 配置?,超過部分進(jìn)行延遲處理,若超過3個(gè)請求/秒俯渤,所有請求都被過度延遲,直到名為req_zone的limit_req_zone 配置設(shè)置的1M存儲(chǔ)區(qū)被占滿,如果存儲(chǔ)區(qū)耗盡呆细,則刪除最近最少使用的狀態(tài)。即使在此之后無法創(chuàng)建新狀態(tài)八匠,請求也會(huì)因錯(cuò)誤而終止絮爷。

????????????????????#limit_req zone=req_zone burst=3;

????????????????????#請求限制 :?對(duì)于符合名為req_zone的limit_req_zone 配置(對(duì)于同一ip的請求,限制平均速率為1個(gè)請求/秒) 若超過1個(gè)請求/秒梨树,所有請求都被過度延遲,直到名為req_zone的limit_req_zone 配置設(shè)置的1M存儲(chǔ)區(qū)被占滿,如果存儲(chǔ)區(qū)耗盡坑夯,則刪除最近最少使用的狀態(tài)。即使在此之后無法創(chuàng)建新狀態(tài)抡四,請求也會(huì)因錯(cuò)誤而終止柜蜈。

????????????????????#limit_req zone=req_zone;

? ? ????????}

基本指令

limit_req_zone

語法:limit_req_zone?key zone=name:size rate=rate;

只能在http塊中使用

此指令用于聲明請求限制zonezone可以保存各種key的狀態(tài)指巡,namezone的唯一標(biāo)識(shí)淑履,size代表zone的內(nèi)存大小,rate指定速率限制藻雪。

參數(shù)詳解:

1.key秘噪,

若客戶的請求匹配了key,則進(jìn)入zone阔涉±峦蓿可以是文本、變量瑰排,通常為Nginx變量贯要。

$binary_remote_addr(客戶的ip),$uri(不帶參數(shù)的請求地址)椭住,$request_uri(帶參數(shù)的請求地址)崇渗,$server_name(服務(wù)器名稱)

支持組合使用,使用空格隔開宅广。

2.zone

使用zone=test葫掉,指定此zone的名字為test。

3.size

在zone=name后面緊跟:size跟狱,指定此zone的內(nèi)存大小俭厚。如zone=name:10m,代表name的共享內(nèi)存大小為10m驶臊。通常情況下挪挤,1m可以保存16000個(gè)狀態(tài)。

4.rate

使用rate=1r/s关翎,限制平均1秒不超過1個(gè)請求扛门。使用rate=1r/m,限制平均1分鐘不超過1個(gè)請求纵寝。

例子:

limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;

limit_req_zone $binary_remote_addr $uri zone=two:10m rate=1r/s;

同一ip不同請求地址论寨,進(jìn)入名為one的zone,限制速率為5請求/秒爽茴。

同一ip同一請求地址葬凳,進(jìn)入名為two的zone,限制速率為1請求/秒闹啦。

limit_req?zone

語法:limit_req?zone=name [burst=number] [nodelay];

可在http, server, location塊中使用

此指令用于設(shè)置共享的內(nèi)存zone和最大的突發(fā)請求大小沮明。

若請求速率超過了limit_req_zone中指定的rate但小于limit_req中的burst,則進(jìn)行延遲處理窍奋,若再超過burst荐健,就可以通過設(shè)置nodelay對(duì)其進(jìn)行丟棄處理。

參數(shù)詳解:

1.zone

使用zone=name指定使用名為namezone琳袄,這個(gè)zone之前使用limit_req_zone聲明過江场。

2.burst(可選)

burst用于指定最大突發(fā)請求數(shù)。許多場景下窖逗,單一地限制rate并不能滿足需求址否,設(shè)置burst,可以延遲處理超過rate限制的請求碎紊。

3.nodelay(可選)

如果設(shè)置了nodelay佑附,在突發(fā)請求數(shù)大于burst時(shí),會(huì)丟棄掉這部分請求仗考。因?yàn)槿绻皇茄舆t處理音同,就像”漏斗“,一旦上面加得快(請求)秃嗜,下面漏的慢(處理速度)权均,”漏斗“總會(huì)有溢出的時(shí)候顿膨。這時(shí),丟棄掉溢出的部分就顯得很有意義了叽赊。

單客戶分為三種情況:

請求速率 < rate(1r/s)恋沃,正常處理

rate(1r/s) < 請求速率 < burst(5r/s),大于rate部分延遲

burst(5r/s)? < 請求速率必指,大于burst部分丟棄(返回503服務(wù)暫時(shí)不可用)


做個(gè)演示:

未開啟請求限制時(shí)做個(gè)壓力測試 (不懂a(chǎn)b的可以看看https://www.cnblogs.com/TingJie/articles/4974885.html這個(gè)文章 , 很簡單明了)

ab -n 100000 -c 1000 http://192.168.58.100/index.html?

Complete requests:? ? ? 10000

Failed requests:? ? ? ? 0

這里模擬了10萬個(gè)請求 , 1000個(gè)并發(fā) , 全部請求成功! 想想一下 , 如果我們是一個(gè)商城程序的API接口 , 正常情況下,同一個(gè)IP下10萬個(gè)請求算不算惡意攻擊?那么就需要做一下請求限制了噻 , 具體怎么限制根絕具體的邏輯去處理 , 我們這里簡單的限制一下:

同一ip請求囊咏,進(jìn)入名為req_zone的zone,限制速率為20次請求/秒,

超過部分進(jìn)行延遲處理取劫,若超過10個(gè)請求/秒匆笤,丟棄超過部分研侣。

http {

? ? limit_req_zone $binary_remote_addr zone=req_zone:1m rate=20r/s;

????server {

? ? ? ? ? ? ...

? ? ????????location / {

? ? ? ? ? ? ? ? ? ? ...

????????????????????#limit_req zone=req_zone burst=10 nodelay;

? ? ????????}

修改了配置之后平滑重啟一下nginx -s reload , 再次使用之前的參數(shù)做個(gè)壓力測試看看

同一IP發(fā)起了請求10萬次, nginx只接受處理了100次,是不是nginx的壓力一下子就小了

Complete requests: 100000

Failed requests:? ? ? ? 99900

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谱邪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子庶诡,更是在濱河造成了極大的恐慌惦银,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件末誓,死亡現(xiàn)場離奇詭異扯俱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)喇澡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門迅栅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晴玖,你說我怎么就攤上這事读存。” “怎么了呕屎?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵让簿,是天一觀的道長。 經(jīng)常有香客問我秀睛,道長尔当,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任蹂安,我火速辦了婚禮椭迎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘田盈。我一直安慰自己畜号,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布缠黍。 她就那樣靜靜地躺著弄兜,像睡著了一般药蜻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上替饿,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天语泽,我揣著相機(jī)與錄音,去河邊找鬼视卢。 笑死踱卵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的据过。 我是一名探鬼主播惋砂,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼绳锅!你這毒婦竟也來了西饵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤鳞芙,失蹤者是張志新(化名)和其女友劉穎眷柔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體原朝,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驯嘱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了喳坠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鞠评。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖壕鹉,靈堂內(nèi)的尸體忽然破棺而出剃幌,到底是詐尸還是另有隱情,我是刑警寧澤御板,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布锥忿,位于F島的核電站,受9級(jí)特大地震影響怠肋,放射性物質(zhì)發(fā)生泄漏敬鬓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一笙各、第九天 我趴在偏房一處隱蔽的房頂上張望钉答。 院中可真熱鬧,春花似錦杈抢、人聲如沸数尿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽右蹦。三九已至诊杆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間何陆,已是汗流浹背晨汹。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贷盲,地道東北人淘这。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像巩剖,于是被迫代替她去往敵國和親铝穷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容