购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.6 Nginx限流

在系统高峰期间存在高并发、系统被外界攻击等一系列潜在风险,为此Nginx提供了限流的策略,以规避掉潜在风险,整体提高系统的安全性。Nginx使用漏桶算法按请求速率对模块进行限速,即能够强行保证请求的实时处理速度不会超过设置的阈值。漏桶算法思想如下:

1)水(请求)从上方倒入水桶,从水桶下方流出(被处理);

2)来不及流出的水存在水桶中(缓冲),以固定速率流出;

3)水桶满后水溢出(丢弃);

4)请求放入缓存,匀速处理,多余的请求直接丢弃。

Nginx限制频率的代码如代码清单4-16所示。

代码清单4-16 Nginx限制频率
limit_conn_log_level notice;
    limit_conn_status 503;
    limit_conn_zone $server_name zone=perserver:10m;
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_req_zone $binary_remote_addr zone=zachary:100m  rate=2r/s;

    server {
        listen 80;
        limit_conn perserver 250;
        limit_conn perip 2;
        limit_req  zone=zachary;
        limit_rate_after 5m;
        limit_rate 800k;
        location / {
            proxy_pass http:// zachary.sh.cn;
        }
    }

其中,$binary_remote_addr通过remote_addr这个标识来限制同一客户端IP地址。

zone=perip:10m;表示生成一个大小为10MB,名称为one的内存区域,用来存储访问的频次信息。

rate=2r/s表示允许相同标识的客户端的访问频次为每秒2次,zone=zachary表示使用zachary区域来做限制。

当单个IP在50ms内发送了8个请求时,处理流程为:Nginx的限流统计是基于毫秒的,设置的速度是2r/s,换算成毫秒是500ms内单个IP允许通过1个请求。所以,当前只有1个请求会被处理,其余7个请求会被直接拒绝。真实网络环境中请求到来不是匀速的,很可能有“突发请求”的情况,对于突发请求的处理方式是将其放入缓存,而不是直接拒绝。

Nginx限制频率并缓存处理(排队等待)的代码如代码清单4-17所示。

代码清单4-17 Nginx限制频率并缓存处理/排队等待
limit_req_zone $binary_remote_addr zone=zachary:100m  rate=2r/s;
    server {
        listen 80;
        limit_conn perserver 250;
        limit_conn perip 2;
        limit_req  zone=zachary  burst=3;
        limit_rate_after 5m;
        limit_rate 800k;
        location / {
            proxy_pass http:// zachary.sh.cn;
        }
    }

其中,burst=3表示设置了一个大小为3的缓冲区,即每个IP最多允许3个突发请求的到来,burst的作用是让多余的请求可以先放到队列里,慢慢处理。

如代码清单4-17所示,1个请求被立即处理,3个请求被放到burst队列里,另外4个请求被拒绝。被放到burst队列里的3个请求,系统会每隔500ms(rate=2r/s)取一个请求进行处理,最后一个请求要等待1.5s才会被处理,显然请求排队的时间会比较长。

Nginx限制频率并缓存处理(不排队等待)的代码如代码清单4-18所示。

代码清单4-18 Nginx限制频率并缓存处理/不排队等待
limit_req_zone $binary_remote_addr zone=zachary:100m  rate=2r/s;

    server {
        listen 80;
        limit_conn perserver 250;
        limit_conn perip 2;
        limit_req  zone=zachary  burst=3 nodelay;
        limit_rate_after 5m;
        limit_rate 800k;
        location / {
            proxy_pass http:// zachary.sh.cn;
        }
    }

其中,nodelay表示超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会排队等待。

nodelay能降低排队时间,nodelay参数允许请求在排队的时候被立即处理,只要请求能够进入burst队列,就会立即被后台worker处理。

当单个IP在50ms内发送了8个请求时,处理流程为:1个请求被立即处理,3个请求被放到burst队列里,另外4个请求被拒绝。

由于队列中的请求同时具有了被处理的资格,所以4个请求是同时被处理的,花费的时间自然变短了。

使用Nginx限流时,应当设置自定义状态,如代码清单4-19所示。 yzjZkafRgJAp95oM5/Qf6o10w1ckOjV8Pmu7OEuceV9S/ZCuPGhJ6aMv9EaXOjJ0

代码清单4-19 自定义设置状态
limit_req_zone $binary_remote_addr zone=zachary:100m  rate=2r/s;
    server {
        listen 80;
        limit_conn perserver 250;
        limit_conn perip 2;
        limit_req  zone=zachary  burst=3 nodelay;
        limit_req_status 600;
        limit_rate_after 5m;
        limit_rate 800k;
        location / {
            proxy_pass http:// zachary.sh.cn;
        }
    }
点击中间区域
呼出菜单
上一章
目录
下一章
×