• NGINX 限流配置


    NGINX限流配置

    摘自:https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/

    介绍

    使用 NGINX 和 NGINX Plus,可以限制:

    • 每个键值的连接数(例如,每个 IP 地址)
    • 每个键值的请求率(一秒或一分钟内允许处理的请求数)
    • 连接的下载速度

    请注意,IP 地址可以在 NAT 设备后面共享,因此应明智地使用 IP 地址限制。

    限制连接数

    限制连接数:

    1. 使用limit_conn_zone指令来定义键并设置共享内存区域的参数(工作进程将使用该区域来共享键值的计数器)。作为第一个参数,指定计算为键的表达式。在第二个参数zone中,指定区域的名称及其大小:

      limit_conn_zone $binary_remote_addr zone=addr:10m;
      
    2. 使用limit_conn指令在 、 或 上下文中location {}应用server {}限制http {}第一个参数指定共享内存区域的名称,第二个参数指定每个键允许的连接数:

      location /download/ {
           limit_conn addr 1;
      }
      

      由于该$binary_remote_addr变量被用作键,因此连接数受限于 IP 地址。

      限制给定服务器的连接数的另一种方法是使用$server_name变量:

      http {
          limit_conn_zone $server_name zone=servers:10m;
      
          server {
              limit_conn servers 1000;
          }
      }
      

    限制请求率

    限速可用于防止 DDoS 攻击,或防止上游服务器同时被太多请求淹没。该方法基于以下leaky bucket算法:请求以各种速率到达存储桶并以固定速率离开存储桶。

    在使用限速之前,您需要配置“漏桶”的全局参数:

    • key - 用于区分一个客户端和另一个客户端的参数,通常是一个变量
    • 共享内存区域 - 保存这些键状态的区域的名称和大小(“漏桶”)
    • r/srate - 每秒请求数 ( ) 或每分钟请求数( )中指定的请求速率限制r/m(“漏桶耗尽”)。每分钟请求数用于指定小于每秒一个请求的速率。

    这些参数是使用limit_req_zone指令设置的。该指令在http {}级别上定义 - 这种方法允许将不同的区域和请求溢出参数应用于不同的上下文:

    http {
        #...
        limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    }
    

    使用此配置,将one创建大小为 10 兆字节的共享内存区域。该区域保持使用该$binary_remote_addr变量设置的客户端 IP 地址的状态。请注意,与它相比$remote_addr,它还保存客户端的 IP 地址,$binary_remote_addr保存 IP 地址的二进制表示,它更短。

    共享内存区域的最佳大小可以使用以下数据来计算:$binary_remote_addr对于 IPv4 地址,value 的大小为 4 字节,存储状态在 64 位平台上占用 128 字节。因此,大约 16,000 个 IP 地址的状态信息占用了 1 兆字节的区域。

    如果 NGINX 需要添加新条目时存储空间耗尽,它会删除最旧的条目。如果释放的空间仍然不足以容纳新记录,NGINX 返回状态码503 Service Unavailable可以使用limit_req_status指令重新定义状态代码。

    设置区域后,您可以在 NGINX 配置中的任何位置使用请求限制,并为 a 或context 指定limit_reqserver {}location {}http {}

    http {
        #...
    
        limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    
        server {
            #...
    
            location /search/ {
                limit_req zone=one;
            }
        }
    }
    

    使用此配置,NGINX 将在该位置1内每秒处理不超过请求。/search/这些请求的处理以这样一种方式延迟,即总速率不大于指定的速率。如果请求数量超过指定速率,NGINX 将延迟处理此类请求,直到“桶”(共享内存区域one)已满。对于到达完整存储桶的请求,NGINX 将响应503 Service Unavailable错误(如果未使用limit_req_status重新定义)。

    测试请求速率限制

    在配置实际限速之前,可以尝试不限制请求处理速率的“dry run”模式。但是,此类过多的请求仍会记入共享内存区域并记录下来。可以使用limit_req_dry_run指令启用“试运行”模式:

    http {
        #...
    
        limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    
        server {
            #...
    
            location /search/ {
                limit_req zone=one;
                limit_req_dry_run on;
            }
        }
    }
    

    每个超出定义速率限制的请求都将被记录为“试运行”标记:

    2019/09/03 10:28:45 [error] 142#142: *13246 limiting requests, dry run, excess: 1.000 by zone "one", client: 172.19.0.1, server: www.example.com, request: "GET / HTTP/1.0", host: "www.example.com:80"
    

    处理过多的请求

    请求被限制为符合limit_req_zone指令中定义的速率。如果请求的数量超过指定的速率并且共享内存区域已满,NGINX 将响应错误。由于流量往往是突发的,因此在流量突发期间返回错误以响应客户端请求并不是最好的情况。

    NGINX 中这种过多的请求可以被缓冲和处理。limit_req指令的burst参数设置等待以指定速率处理的过多请求的最大数量:

    http {
        #...
    
        limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    
        server {
            #...
    
            location /search/ {
                limit_req zone=one burst=5;
            }
        }
    }
    

    使用此配置,如果请求速率超过1每秒请求,则超出该速率的请求将被放入 zone one当 zone 已满时,过多的请求会被排队(burst),这个队列的大小是5requests。队列中的请求处理以这样的方式延迟,即总速率不大于指定的速率。超出突发限制的请求将被拒绝并出现503错误。

    如果在流量突发期间不希望请求延迟,请添加nodelay参数:

    http {
        #...
    
        limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    
        server {
            #...
    
            location /search/ {
                limit_req zone=one burst=5 nodelay;
            }
        }
    }
    

    burst使用此配置,无论指定如何,都会立即处理限制内的过多请求rate,超过突发限制的请求将被拒绝并出现503错误。

    延迟过多的请求

    处理过多请求的另一种方法是立即处理一些此类请求,然后应用速率限制,直到拒绝过多请求为止。

    这可以通过delayburst参数来实现。delay参数定义了延迟过多请求以符合定义的速率限制的点:

    http {
        #...
    
        limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    
        server {
            #...
    
            location /search/ {
                limit_req zone=one burst=5 delay=3;
            }
        }
    }
    

    使用此配置,前 3 个请求 ( delay) 会立即通过,接下来的 2 个请求 ( burstdelay) 会延迟,以使总速率不大于指定的速率,因为超过了总突发大小,将拒绝更多的请求,后续请求将被延迟。

    同步多个共享内存区域的内容

    如果您有一个具有多个 NGINX 实例的计算机集群并且这些实例使用该limit_req方法,则可以在以下条件下同步其共享内存区域的内容:

    http {
        #...
        limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s sync;
    }
    

    有关详细信息,请参阅集群中的运行时状态共享

    限制带宽

    要限制每个连接的带宽,请使用limit_rate指令:

    location /download/ {
        limit_rate 50k;
    }
    

    使用此设置,客户端将能够通过单个连接以50每秒千字节的最大速度下载内容。但是,客户端可以打开多个连接。因此,如果目标是防止下载速度大于指定值,则还应限制连接数。例如,每个 IP 地址一个连接(如果使用上面指定的共享内存区域):

    location /download/ {
        limit_conn addr 1;
        limit_rate 50k;
    }
    

    要仅在客户端下载一定数量的数据后施加限制,请使用limit_rate_after指令。允许客户端快速下载一定量的数据(例如,文件头——电影索引)并限制下载其余数据的速率(让用户观看电影,而不是下载)可能是合理的。

    limit_rate_after 500k;
    limit_rate       20k;
    

    以下示例显示了用于限制连接数和带宽的组合配置。允许的最大连接数设置为5 每个客户端地址的连接数,这适合大多数常见情况,因为现代浏览器通常一次最多打开 3 个连接。同时,提供下载的位置只允许一个连接:

    http {
        limit_conn_zone $binary_remote_address zone=addr:10m
    
        server {
            root /www/data;
            limit_conn addr 5;
    
            location / {
            }
    
            location /download/ {
                limit_conn       addr 1;
                limit_rate_after 1m;
                limit_rate       50k;
            }
        }
    }
    

    动态带宽控制

    limit_rate也可以指定为变量 - 这可以启用动态带宽用例,例如,允许对现代浏览器进行更高的带宽限制:

    map $ssl_protocol $response_rate {
        "TLSv1.1" 10k;
        "TLSv1.2" 100k;
        "TLSv1.3" 1000k;
    }
    
    server {
        listen 443 ssl;
        ssl_protocols       TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
    
        location / {
            limit_rate       $response_rate; # Limit bandwidth based on TLS version
            limit_rate_after 512;      # Apply limit after headers have been sent
            proxy_pass       http://my_backend;
        }
    }
  • 相关阅读:
    struts2 标签的使用之二 s:iterator
    struts2 标签的使用之一 s:if
    java Tomcat数据库连接池
    JNDI:对java:comp/env的研究
    ***Tomcat7.0安装配置
    ***tomcat配置文件server.xml详解
    宜昌IT软件资源汇总
    tomcat安全设置
    tomcat部署javaweb项目的三种方式
    Tomcat在Linux上的安装与配置
  • 原文地址:https://www.cnblogs.com/AmbitiousMice/p/16285714.html
Copyright © 2020-2023  润新知