Nginx接入层限流

      对于Nginx接入层限流通常可以使用 Nginx自带的两个模块:

      1、连接数限流模块:ngx_http_limit_conn_module

      可以对某个key,如按照IP、域名对应的总的网络连接数进行限流。

  • 示例 1.1 :按照IP限制并发连接数限流
http {
    ...
    limit_conn_zone $binary_remote_addr zone=perip:10m; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)
    limit_conn_log_level error; #配置被限流后日志级别
    limit_conn_status 503; #配置被限流后返回的状态码
    ...
    server {
        ...
        #在要限流的location中添加限流逻辑
        location /
        {
            limit_conn perip 2; #存放key和计数器的共享内存区域 和 指定key的最大连接数
        }
    }
    ...
    
    access_log  /www/wwwlogs/oyhdo.com.log;
    error_log  /www/wwwlogs/oyhdo.com.error.log;
}

      以上配置表示:限制每个IP最大并发连接数为2。

      ab测试:并发数5,总请求数5,命令如下:

ab -n 5 -c 5 https://oyhdo.com/

     打印access_log结果如下:

      

      error_log结果:(被限流)

      

 

  • 示例 1.2 :按照域名限制并发连接数限流
http {
    ...
    limit_conn_zone $server_name zone=perserver:10m; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)
    limit_conn_log_level error; #配置被限流后日志级别
    limit_conn_status 503; #配置被限流后返回的状态码
    ...
    server {
        ...
        #在要限流的location中添加限流逻辑
        location /
        {
            limit_conn perserver 2; #存放key和计数器的共享内存区域 和 指定key的最大连接数
        }
    }
    ...
 
    access_log  /www/wwwlogs/oyhdo.com.log;
    error_log  /www/wwwlogs/oyhdo.com.error.log;
}

      以上配置表示:限制每个域名最大并发请求连接数为2。 

      ab测试:并发数5,总请求数5,命令如下:

ab -n 5 -c 5 https://oyhdo.com/

     打印access_log结果如下:

      

      error_log结果:

      

 

      2、漏桶算法实现的请求限流模块:ngx_http_limit_req_module 

      可以对某个key,如按照IP、域名对应的请求的平均速率进行限流,有两种用法:平滑模式(delay)、允许突发模式(nodelay),也称为延迟模式和非延迟模式。

  • 示例 2.1 :按照IP限流
http {
    ...
    limit_req_zone $binary_remote_addr zone=perip:10m rate=500r/s; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)、固定请求速率rate(如10r/s为每秒10个请求,60r/m为每分钟60个请求)
    limit_conn_log_level error; #配置被限流后日志级别
    limit_conn_status 503; #配置被限流后返回的状态码
    ...
    server {
        ...
        #在要限流的location中添加限流逻辑
        location /
        {
            limit_req zone=perip; #配置限流区域zone、桶容量(突发容量,默认burst=0)、是否延迟模式(默认延迟delay,非延迟nodelay)
        }
    }
    ...
    
    access_log  /www/wwwlogs/oyhdo.com.log;
    error_log  /www/wwwlogs/oyhdo.com.error.log;
}

      以上配置表示:限制每秒500个请求,即平均速率为2毫秒一个请求;桶容量(burst)为0;延迟模式

      ab测试:并发数2,总请求数10,命令如下:

ab -n 10 -c 2 https://oyhdo.com/

     打印access_log结果如下:(虽然允许每秒500个请求,但是桶容量为0,所以流入的请求要么被处理要么被限流,无法延迟处理)

      Nginx接入层限流_第1张图片

      error_log结果:

      

 

  • 示例 2.2 :按照IP限流
http {
    ...
    limit_req_zone $binary_remote_addr zone=perip:10m rate=2r/s; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)、固定请求速率rate(如10r/s为每秒10个请求,60r/m为每分钟60个请求)
    limit_conn_log_level error; #配置被限流后日志级别
    limit_conn_status 503; #配置被限流后返回的状态码
    ...
    server {
        ...
        #在要限流的location中添加限流逻辑
        location /
        {
            limit_req zone=perip burst=3; #配置限流区域zone、桶容量(突发容量,默认burst=0)、是否延迟模式(默认延迟delay,非延迟nodelay)
        }
    }
    ...
    
    access_log  /www/wwwlogs/oyhdo.com.log;
    error_log  /www/wwwlogs/oyhdo.com.error.log;
}

      以上配置表示:限制每秒2个请求,即平均速率为500毫秒一个请求;桶容量(burst)为3;延迟模式

      ab测试:执行一个req.sh脚本,命令如下:(进行6个并发请求6次URL,休眠300毫秒,重复请求)

ab -n 6 -c 6 https://oyhdo.com/
sleep 0.3
ab -n 6 -c 6 https://oyhdo.com/

     打印access_log结果如下:(预计超过桶容量3会限制请求,由于算法精度问题会有一些偏差,每轮流入了4个请求,另外做了延迟处理)

      Nginx接入层限流_第2张图片

      error_log结果:

      Nginx接入层限流_第3张图片

 

  • 示例 2.3 :按照IP限流
http {
    ...
    limit_req_zone $binary_remote_addr zone=perip:10m rate=2r/s; #配置限流key与其存放信息的共享内存大小($binary_remote_addr为IP限流,$server_name为域名限流)、固定请求速率rate(如10r/s为每秒10个请求,60r/m为每分钟60个请求)
    limit_conn_log_level error; #配置被限流后日志级别
    limit_conn_status 503; #配置被限流后返回的状态码
    ...
    server {
        ...
        #在要限流的location中添加限流逻辑
        location /
        {
            limit_req zone=perip burst=3 nodelay; #配置限流区域zone、桶容量(突发容量,默认burst=0)、是否延迟模式(默认延迟delay,非延迟nodelay)
        }
    }
    ...
    
    access_log  /www/wwwlogs/oyhdo.com.log;
    error_log  /www/wwwlogs/oyhdo.com.error.log;
}

      以上配置表示:限制每秒2个请求,即平均速率为500毫秒一个请求;桶容量(burst)为3;非延迟模式

      ab测试:执行一个req.sh脚本,命令如下:

ab -n 6 -c 6 https://oyhdo.com/
sleep 1
ab -n 6 -c 6 https://oyhdo.com/
sleep 0.3
ab -n 6 -c 6 https://oyhdo.com/
sleep 0.3
ab -n 6 -c 6 https://oyhdo.com/
sleep 0.3
ab -n 6 -c 6 https://oyhdo.com/
sleep 2
ab -n 6 -c 6 https://oyhdo.com/

     打印access_log结果如下:(由于算法精度问题会有一些偏差,第一轮和第六轮流入了4个请求,允许突发请求)

      Nginx接入层限流_第4张图片

      error_log结果:

      Nginx接入层限流_第5张图片

 

你可能感兴趣的:(Nginx)