網上很多類似的文章,但可能沒有一些實際壓測的說明,這裏做簡單說明
配置
#統一在http域中進行配置
#限制請求
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默認是0
limit_req zone=api_read burst=100;
#連接數限制,每個IP併發請求爲50
limit_conn perip_conn 50;
#服務所限制的連接數(即限制了該server併發連接數量)
limit_conn perserver_conn 200;
#連接限速
#limit_rate 100k;
}
壓測效果
1. 未限制
1000 個請求併發100 個客戶端
1000 個請求併發1000 個客戶端
併發100、1000,每秒能處理的請求數相近,因爲這次目的不是壓測nginx 性能,所以沒必要繼續往下壓,這裏壓測主要是跟後面限流後的數據做對比。
2. 配置限流
rate=50r/s # 每秒新增50個令牌
burst=100 # 令牌桶一共有100個令牌
perip_conn 50 # 每個IP最多併發50個連接
perserver_conn 200 # 限制該server併發連接數
1000 個請求併發100 個客戶端
雖然請求沒有失敗,但是明顯地RPS 下降很明顯,請求等待耗時也比不限流要多。
總耗時接近19s,也就是說新增令牌應該是19*50=950,而再加上原來令牌桶有100個令牌,總數是1050個,且perserver_conn=200,按道理也是能夠承接100個客戶端的1000個請求。
10000 個請求併發100 個客戶端
同上,RPS也是接近50左右,請求沒有失敗,請求等待耗時跟上面一樣
總壓測耗時200s,新增令牌數:200*50=10000,沒毛病
10000 個請求併發1000 個客戶端
RPS漲到4k多,但是從壓測結果來看,接近99%的請求都是失敗的,也就是說4k多裏面接近99%都是失敗的請求
nginx 限制了該server最多隻能接受200個併發連接,所以只要nginx接收到的併發數小於200,nginx都能夠處理,但由於令牌桶的限制,nginx最多隻能同時處理100個請求,其餘的請求會進行排隊,並且會在每秒內在生成50個令牌提供給排隊中的請求。
3. 匹配指定路徑進行限流
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 下的所有請求進行限流,但是有個問題是:該url 下是產品的鏈接,而所有產品鏈接都是在該url下以產品id 進行區分,這樣限流相當於將所有產品都進行限流,如果有某個爆款產品把鏈接佔用完了,會影響其他常規產品的訪問。
正常一個產品鏈接: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