前沿?zé)狳c:Nginx與LUA(3)

2023-01-16 11:30:18 來源:51CTO博客

您好,我是湘王,這是我的51CTO博客,歡迎您來,歡迎您再來~


在互聯(lián)網(wǎng)應(yīng)用中,很多場景都會涉及到高并發(fā)請求,如果不對這些請求做限制,那么服務(wù)器很快就會被擠垮。就像在12306買票一樣,如果全國人民都去搶票,服務(wù)器是無論如何也扛不住壓力的。

這是非常現(xiàn)實的而且也是必須要解決的問題。


(資料圖片)

其實,除了反向代理和負(fù)載均衡,網(wǎng)絡(luò)限流也是Nginx的拿手好戲。

常用于實現(xiàn)網(wǎng)絡(luò)限流的兩類算法有:

1、令牌桶;

2、漏桶。

而Nginx實現(xiàn)限流的兩種方式是:

1、限制訪問頻率,就是限制指定時間內(nèi)每個用戶的訪問次數(shù);

2、限制并發(fā)連接數(shù),就是限制某段時間內(nèi)訪問資源的用戶數(shù)。

Nginx限流模塊使用的是漏桶算法。

令牌桶限流的算法思想是:

1、令牌以固定速率產(chǎn)生,并緩存到令牌桶;

2、令牌桶放滿時,多余的令牌將被直接丟棄;

3、請求進來時,先進入待處理的請求隊列;

4、處理請求時需要從桶里拿到相應(yīng)數(shù)量的令牌作為處理「憑證」;

5、當(dāng)桶里沒有令牌時,請求處理被拒絕。

令牌桶是一種常用于網(wǎng)絡(luò)流量整形和速率限制的算法,只有持有令牌的請求才會被處理,這也是令牌桶名稱的由來。令牌桶算法允許突發(fā)流量的存在,更適合會有突發(fā)流量的場景。

而漏桶限流的算法思想是:

水(請求)從上方進入水桶,從下方流出(被處理),來不及流出的水存在水桶中(緩沖),以固定速率流出。水桶滿后水溢出(丟棄請求)。漏桶也是一種常用的整形和限速算法,其核心是緩存請求、勻速處理、多余丟棄。

正如漏桶一樣,不管突然增加多少水量,底部的漏洞始終保持著勻速的出水量,這正是漏桶算法名稱的由來。因此漏桶算法會屏蔽突發(fā)請求,更適合需要平滑流量的場景。

漏桶算法與令牌桶算法看起來很類似,容易弄混。實際上這兩者具有截然不同的特性,應(yīng)用在不同的場景中。真正區(qū)分令牌桶和漏桶最核心的特征是「變速」和「勻速」:

1、令牌桶是一種變速運動——就像高速上的汽車一樣;

2、漏桶是一種勻速運動——就像鐵軌上的火車一樣。

這兩種限流算法沒有優(yōu)劣好壞之分,只區(qū)分場景的適用性。

為了驗證這兩種縣里算法,可以做一個簡單的測試。ab是apachebench命令的縮寫,是一款比較優(yōu)秀的壓測工具。在安裝Nginx的機器上安裝ab,如果不想安裝apache但是又想使用ab命令的話,可以這樣做:

yum -y install httpd-tools

cd /usr/bin

ab -V

ab的使用也很簡單:

./ab -h:獲取幫助

./ab -n1000 -c100 -t1 -s5 http://localhost/test?username=test1

意思是:發(fā)送1000次,每次100個并發(fā)請求到指定服務(wù),并在1秒之內(nèi)完成請求,超時時間5秒。如果只是-n100、-c10參數(shù),只能看到總的請求次數(shù)100次,看不到并發(fā)請求環(huán)境下是否真的滿足限流要求。

如果加上-t、-s參數(shù),就能很清楚地看到限流效果。

ab測試完成后的結(jié)果可能是這個樣子的:

用Nginx限制訪問速率可以這樣寫:限制每個IP的訪問速率為每秒10次。

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

server {

listen 80;

server_name localhost;

location / {

limit_req zone=case1;

}

}

ab測試命令:

./ab -n100 -c10 -t1 -s5 http://localhost/test?username=test1

./ab -n100 -c10 -t2 -s5 http://localhost/test?username=test1(多線程影響)

結(jié)果滿足要求:

Complete requests:30397;Failed requests:30387

用Nginx限制突發(fā)增量可以這樣寫:限制每個IP的訪問速率為每秒10次,有burst且直接返回。

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

server {

listen 80;

server_name localhost;

location / {

limit_req zone=case1 burst=5 nodelay;

}

}

ab測試命令:

./ab -n100 -c10 -t1 -s5 http://localhost/test?username=test1

./ab -n100 -c10 -t2 -s5 http://localhost/test?username=test1(多線程影響)

結(jié)果觀察:

Complete requests:15212;Failed requests:15197

用Nginx限制并發(fā)訪問:限制每個IP的并發(fā)請求為10。

limit_conn_zone $binary_remote_addr zone=case2:10m;

server {

listen 80;

server_name localhost;

location / {

limit_conn case2 10;

}

}

ab測試命令:

./ab -n100 -c10 -t1 -s5 http://localhost/test?username=test1

./ab -n100 -c11 -t1 -s5 http://localhost/test?username=test1

結(jié)果觀察:

當(dāng)參數(shù)為c10,所有請求全部成功;當(dāng)參數(shù)為c11,出現(xiàn)請求失敗的情況

限制并發(fā)訪問:按服務(wù)名。

限制每個服務(wù)的并發(fā)請求為10

limit_conn_zone $server_name zone=case3:10m;

server {

listen 80;

server_name localhost;

location / {

limit_conn case3 10;

}

}

ab測試命令:

./ab -n100 -c10 -t1 -s5 http://localhost/test?username=test1

./ab -n100 -c11 -t1 -s5 http://localhost/test?username=test1

結(jié)果觀察:

當(dāng)參數(shù)為c10,所有請求全部成功;當(dāng)參數(shù)為c11,出現(xiàn)請求失敗的情況

還可以自定義返回值:配置status返回值

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

server {

listen 80;

server_name localhost;

location / {

limit_conn case1 10;

limit_req_status 599;

}

}

ab測試命令:

./ab -n100 -c10 -t1 -s5 http://localhost/test?username=test1

ab看不到效果,需要用其他更專業(yè)測試工具,比如Postman。


感謝您的大駕光臨!咨詢技術(shù)、產(chǎn)品、運營和管理相關(guān)問題,請關(guān)注后留言。歡迎騷擾,不勝榮幸~

?

標(biāo)簽: 測試命令 很快就會

上一篇:當(dāng)前關(guān)注:HBase的索引
下一篇:全球要聞:基于阿里云的 Terraform 入門實戰(zhàn)