网上很多类似的文章,但可能没有一些实际压测的说明,这里做简单说明
配置
#统一在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 个客户端
![](https://img.haomeiwen.com/i9244640/82d71ce481d4153f.png)
1000 个请求并发1000 个客户端
![](https://img.haomeiwen.com/i9244640/b5f2d4464667c4ad.png)
并发100、1000,每秒能处理的请求数相近,因为这次目的不是压测nginx 性能,所以没必要继续往下压,这里压测主要是跟后面限流后的数据做对比。
2. 配置限流
rate=50r/s # 每秒新增50个令牌
burst=100 # 令牌桶一共有100个令牌
perip_conn 50 # 每个IP最多并发50个连接
perserver_conn 200 # 限制该server并发连接数
1000 个请求并发100 个客户端
![](https://img.haomeiwen.com/i9244640/bafb369953aef02a.png)
虽然请求没有失败,但是明显地RPS 下降很明显,请求等待耗时也比不限流要多。
总耗时接近19s,也就是说新增令牌应该是19*50=950,而再加上原来令牌桶有100个令牌,总数是1050个,且perserver_conn=200,按道理也是能够承接100个客户端的1000个请求。
10000 个请求并发100 个客户端
![](https://img.haomeiwen.com/i9244640/073f8b4bf78b9c2c.png)
同上,RPS也是接近50左右,请求没有失败,请求等待耗时跟上面一样
总压测耗时200s,新增令牌数:200*50=10000,没毛病
10000 个请求并发1000 个客户端
![](https://img.haomeiwen.com/i9244640/83b7750d5f7dad23.png)
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
![](https://img.haomeiwen.com/i9244640/e6040ad24657fdd6.png)
网友评论