網(wǎng)上很多類似的文章,但可能沒有一些實際壓測的說明,這里做簡單說明
配置
#統(tǒng)一在http域中進(jìn)行配置
#限制請求
limit_req_zone $uri zone=api_read:20m rate=50r/s;
#按ip配置一個連接 zone
limit_conn_zone $binary_remote_addr zone=perip_conn:10m;
#按server配置一個連接 zone
limit_conn_zone $server_name zone=perserver_conn:100m;
===== server =====
location / {
if (!-e $request_filename){
rewrite ^/(.*) /index.php last;
}
#請求限流排隊通過 burst默認(rèn)是0
limit_req zone=api_read burst=100;
#連接數(shù)限制,每個IP并發(fā)請求為50
limit_conn perip_conn 50;
#服務(wù)所限制的連接數(shù)(即限制了該server并發(fā)連接數(shù)量)
limit_conn perserver_conn 200;
#連接限速
#limit_rate 100k;
}
壓測效果
1. 未限制
1000 個請求并發(fā)100 個客戶端

1000 個請求并發(fā)1000 個客戶端

并發(fā)100、1000,每秒能處理的請求數(shù)相近,因為這次目的不是壓測nginx 性能,所以沒必要繼續(xù)往下壓,這里壓測主要是跟后面限流后的數(shù)據(jù)做對比。
2. 配置限流
rate=50r/s # 每秒新增50個令牌
burst=100 # 令牌桶一共有100個令牌
perip_conn 50 # 每個IP最多并發(fā)50個連接
perserver_conn 200 # 限制該server并發(fā)連接數(shù)
1000 個請求并發(fā)100 個客戶端

雖然請求沒有失敗,但是明顯地RPS 下降很明顯,請求等待耗時也比不限流要多。
總耗時接近19s,也就是說新增令牌應(yīng)該是19*50=950,而再加上原來令牌桶有100個令牌,總數(shù)是1050個,且perserver_conn=200,按道理也是能夠承接100個客戶端的1000個請求。
10000 個請求并發(fā)100 個客戶端

同上,RPS也是接近50左右,請求沒有失敗,請求等待耗時跟上面一樣
總壓測耗時200s,新增令牌數(shù):200*50=10000,沒毛病
10000 個請求并發(fā)1000 個客戶端

RPS漲到4k多,但是從壓測結(jié)果來看,接近99%的請求都是失敗的,也就是說4k多里面接近99%都是失敗的請求
nginx 限制了該server最多只能接受200個并發(fā)連接,所以只要nginx接收到的并發(fā)數(shù)小于200,nginx都能夠處理,但由于令牌桶的限制,nginx最多只能同時處理100個請求,其余的請求會進(jìn)行排隊,并且會在每秒內(nèi)在生成50個令牌提供給排隊中的請求。
3. 匹配指定路徑進(jìn)行限流
upstream ykz-www {
server 10.13.14.134:80;
}
server {
listen 80;
server_name www-test.yunkezan.com yunkezan.yaochufa.com www.yunkezan.cn yunkezan.com yunkezan.cn;
error_log /data/logs/www.yunkezan.com.error.log;
access_log /data/logs/www.yunkezan.com.access.log main;
location / {
proxy_pass http://ykz-www;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
location /front/index/specialDetails {
> > limit_req zone=api_read burst=100;
> > limit_conn perip_conn 50;
limit_conn perserver_conn 200;
proxy_pass http://ykz-www;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
include vhost/common/ssl-yunkezan.com.conf;
}
以上配置可以針對/front/index/specialDetails 該url 下的所有請求進(jìn)行限流,但是有個問題是:該url 下是產(chǎn)品的鏈接,而所有產(chǎn)品鏈接都是在該url下以產(chǎn)品id 進(jìn)行區(qū)分,這樣限流相當(dāng)于將所有產(chǎn)品都進(jìn)行限流,如果有某個爆款產(chǎn)品把鏈接占用完了,會影響其他常規(guī)產(chǎn)品的訪問。
正常一個產(chǎn)品鏈接:https://www-test.yunkezan.com/front/index/specialDetails?weChatId=421&goodId=17503&activityId=2027&channel=promoteMall&tag_id=-1&tag_name=%E9%99%90%E6%97%B6%E6%8A%A2%E8%B4%AD&tag2_id=-5&tag2_name=%E7%83%AD%E9%97%A8
返回503 被限流。
#限制請求
#limit_req_zone $uri zone=api_read:20m rate=50r/s;
#按ip配置一個連接 zone
#limit_conn_zone $binary_remote_addr zone=perip_conn:10m;
#按server配置一個連接 zone
#limit_conn_zone $server_name zone=perserver_conn:100m;
#按goodId配置一個連接 zone
