Nginx 限流

电商平台营销时候,经常会碰到的大流量问题,除了做流量分流处理,可能还要做用户黑白名单、信誉分析,进而根据用户ip信誉权重做相应的流量拦截、限制流量。
Nginx自身有的请求限制模块ngx_http_limit_req_module、流量限制模块ngx_stream_limit_conn_module基于令牌桶算法,可以方便的控制令牌速率,自定义调节限流,实现基本的限流控制。

对于提供下载的网站,肯定是要进行流量控制的,例如软件下载站、视频服务等。
它也可以减少一些爬虫程序或者DDOS的攻击。

对这两个模块的介绍的文章也不少,这里转载一篇hopestar的文章: nginx限制IP连接数的范例参考, 因为他介绍的很简洁。


如何Nginx限制同一个ip的连接数,限制并发数目:

限流

(1) 添加limit_zone和limit_req_zone

这个变量只能在http使用 :

[html]  view plain  copy
  1. vi /export/servers/nginx/conf/nginx.conf   
  2. limit_zone one  $binary_remote_addr  20m;  
  3. limit_req_zone  $binary_remote_addr  zone=req_one:20m rate=12r/s;  

(2) 添加limit_conn 和limit_req

这个变量可以在httpserverlocation使用 我是限制nginx上的所有服务,所以添加到http里面 (如果你需要限制部分服务,可在nginx/conf/domains里面选择相应的server或者location添加上便可)

[html]  view plain  copy
  1. vi /export/servers/nginx/conf/nginx.conf   
  2. limit_zone one $binary_remote_addr 20m;  
  3. limit_req_zone $binary_remote_addr zone=req_one:20m rate=12r/s;  
  4. limit_conn one 10;  
  5. limit_req zone=req_one burst=120;  

参数详解(数值按具体需要和服务器承载能力设置,):

[html]  view plain  copy
  1. limit_zone,是针对每个变量(这里指IP,即$binary_remote_addr)定义一个存储session状态的容器。这个示例中定义了一个20m的容器,按照32bytes/session,可以处理640000个session。  
  2. limit_req_zone 与limit_zone类似。rate是请求频率. 每秒允许12个请求。  
  3. limit_conn  one 10 : 表示一个IP能发起10个并发连接数  
  4. limit_req: 与limit_req_zone对应。burst表示缓存住的请求数。  

范例:

[html]  view plain  copy
  1. http  
  2. {  
  3. limit_zone one  $binary_remote_addr  20m;  
  4. limit_req_zone  $binary_remote_addr  zone=req_one:20m rate=12r/s;  
  5. limit_conn   one  10;  
  6. limit_req   zone=req_one burst=120;  
  7. server  {  
  8.         listen          80;  
  9.         server_name     status.xxx.com ;  
  10.         location / {  
  11.                  stub_status            on;  
  12.                  access_log             off;  
  13.         }  
  14. }  
  15. }  

(3) 重启nginx
[javascript]  view plain  copy
  1. /export/servers/nginx/sbin/nginx -s reload  


Nginx限制流量/限制带宽 具体参考官方文档

nginx白名单设置

以上配置会对所有的ip都进行限制,有些时候我们不希望对搜索引擎的蜘蛛或者某些自己的代理机过来的请求进行限制, 对于特定的白名单ip我们可以借助geo指令实现。

先在nginx的请求日志进行统计,查看那个ip的访问量比较大, 运行:

[python]  view plain  copy
  1. cat access.log | grep "03/Jun" |awk '{print $1}'|sort |uniq -c|sort -nrk 1|head -n 10  
  2. #列出访问日志里面在6月3号这天前10个访问量最大的ip.  

接下来就可以对这些IP进行分析了。看哪些需要进行白名单设置。

[javascript]  view plain  copy
  1. http{  
  2.      geo  $limited  { # the variable created is $limited  
  3.       default          1;  
  4.       127.0.0.1/32     0;  
  5.       10.12.212.63     0;  
  6.     }  
  7.     map $limited $limit {  
  8.     1 $binary_remote_addr;  
  9.     0 "";  
  10.     }  
  11.     limit_zone one  $binary_remote_addr  20m;  
  12.     limit_req_zone  $limit  zone=req_one:20m rate=20r/s;  
  13.     limit_conn   one  10;  
  14.     limit_req   zone=req_one burst=120;  
  15. }  

上面两个需要用到map和geo模块,这是nginx自带的模块,有的运维喜欢把他们关闭,自己./sbin/nginx -V 留意一下。把配置的--whithout-XXX-module 去掉重新编译一下就可以了。 上面这段配置的意思是:

1.geo指令定义了一个白名单 limited1ip limited的值为0
2.使用map指令映射搜索引擎客户端的ip为空串,如果不是搜索引擎就显示本身真实的ip,这样搜索引擎ip就不能存到limit_req_zone内存session中,所以不会限制搜索引擎的ip访问

PS:获取客户端的真实IP

顺带一提,为了获取客户端的真实IP。该模块需要安装read_ip模块,运维应该默认有安装。没有的话也可自行安装: 配置方式相当简单,重新编译 Nginx 加上 --with-http_realip_module 参数,如:

[html]  view plain  copy
  1. ./configure --prefix=/opt/nginx --with-http_stub_status_module  --with-pcre=../pcre-6.6 --with-http_realip_module  
  2. make  
  3. make install  

在server中增加:

[html]  view plain  copy
  1. set_real_ip_from   192.168.1.0/24;  
  2. set_real_ip_from   192.168.2.1;  
  3. real_ip_header     [X-Real-IP|X-Forwarded-For];  

需要说明的地方就是设置IP源的时候可以设置单个IP,也可以设置IP段,另外是使用X-Real-IP还是X-Forwarded-For,取决于前面的服务器有哪个头。

set_real_ip_from 设置的IP端可以让运维查看日志,看下你的请求是来自哪些ip段。

重新加载一下服务,差不多就OK了。

再查看日志的话,应该可以看到客户端的真实IP了。

注意:如果未安装该模块的话你的获取到的IP端可能是来自前端代理(如squid)的IP,结果就是多个用户被当成单个用户对待,导致应用不能响应。 参考:http://hi.baidu.com/thinkinginlamp/item/e2cf05263eb4d18e6e2cc3e6

再PS一下: 自测: 有条件的自己可以用ab或者webben自测一下。

未安装前压测的话,因为有大量请求,所以access.log会有大量日志,而error.log日志没有变化。

[html]  view plain  copy
  1. [root@qrwefsdf talk]# webbench  -c 30 -t 30 http://xxx.com    
  2. Webbench - Simple Web Benchmark 1.5  
  3. Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.  
  4. Benchmarking: GET http://xxx.com    
  5. 30 clients, running 30 sec.  
  6. Speed=193468 pages/min, 1254317 bytes/sec.  
  7. Requests: 96734 susceed, 0 failed.  

安装后会发现很多超出的请求会返回503,所以access.log日志变化不快,error.log有大量记录,提示limit_reque缓住了多少请求。

[html]  view plain  copy
  1. [root@qrwefsdf talk]# webbench  -c 30 -t 30 http://xxxx.com  
  2. Webbench - Simple Web Benchmark 1.5  
  3. Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.  
  4. Benchmarking: GET http://xxx.com    
  5. 30 clients, running 30 sec.  
  6. Speed=120 pages/min, 778 bytes/sec.  

  1. Requests: 60 susceed, 0 failed.  

对于提供下载的网站,肯定是要进行流量控制的,例如BBS、视频服务,还是其它专门提供下载的网站。在nginx中我们完全可以做到限流,由Core模块提供了limit_rate、limit_rate_after命令。

 

指    令

 

    通过以下两条命令来完成限制流量。

 

指令名称:limit_rate

功    能:该指令用于指定向客户端传输数据的速度,速度的单位是每秒传输的字节数。需要明白的一点是该限制只是针对一个连接的设定,就是说如果同时有两个连接那么它的速度将会是该指令设置值的2倍,

 

如果需要在server级别对某些客户端限制速度,对于这种情况——这个指令可能并不适合,但是可设置$limit_rate变量,可以为该变量传递相应的值来实现,例如:

 

server {

  if ($slow) {

    set $limit_rate  4k;

  }

}

 

    当然也可以通过设置X-Accel-Limit-Rate头(来自于NginxXSendfile模块)来控制由proxy_pass(来自于HttpProxyModule模块)返回的响应数据的速率,而没有使用X-Accel-Redirect头。

语    法: limit_rate speed

默 认 值: no

使用环境: http, server, location, if in location

 

指    令:limit_rate_after

    能:limit_rate_after,这个命令中的“after”提示了我们,可以这样理解“在后再限制速率为”,没错,就是这个意思,它的语法为:limit_rate_after time(这是官方威客上http://wiki.nginx.org/HttpCoreModule#limit_rate的语法),它的意思是以最大的速度下载time时长后,但是在实际的使用中发现命令limit_rate_after的参数是一个下载字节量的大小值,而不是时间值,因此上面的命令“limit_rate_after 3m”解释为:以最大的速度下载3M后。

语    法:limit_rate_after size

默 认 值:limit_rate_after 1m

使用字段:http, server, location, location中的if字段

 

实例配置

 

    看下面的配置,这是一个视频服务器上的配置片断,通过这两条命令限制了访问者的下载速度:

 

 

   location /download {

       limit_rate_after 3m;

       limit_rate 512k;

    }

 

   

我们看一下这两条命令:

 

 

    limit_rate,相对于limit_rate_after命令,这个命令已经开始限速了,它的语法为:limit_rate speed,它表示限制为的速率。该指令可以用在http, server, location以及location中的if区段,没有默认值。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值