• 使用nginx构建限频、限速、限并发的应用保护层


    使用nginx构建限频、限速、限并发的应用保护层

    nginx本身提供了基础的限频、限速、限并发连接等能力。

    限频

    基于uri等限制某一个客户端,某类客户端持续时间段内建立连接的次数。

    限速
    限制客户端读取、发送数据包的速度,从总体看,即使限制网速。

    限并发

    限制客户端同时允许创建的连接,防止单个客户端创建过多连接耗尽服务器资源。

    限频

    http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

    http {
      # 定义2条限速区域
      # 以 $binary_remote_addr 字段作为限频统计点
      # zone=one:10m # 定义区域名称为one,限统计总占用内存10MB
      # 限制请求频率为 最多1次/per second
      limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    
      # 以 $binary_remote_addr 作为统计限频的依据
      # zone=zone2:32m zone名称定为zone2,定义32MB的统计内存占用
      # 限制请求频率 最多10次/per minute
      limit_req_zone $binary_remote_addr zone=zone2:32m rate=10r/m;
      
      # Sets the desired logging level for cases when the server refuses to 
      # process requests due to rate exceeding, or delays request processing.
      # Logging level for delays is one point less than for refusals; 
      # for example, if “limit_req_log_level notice” is specified, delays are logged with the info level. 
      limit_req_log_level info; # default error, <info | notice | warn | error>
      
      limit_req_status 503; # default 503 added from nginx-1.3.15
      
      server {
        # ...
        
        location /search/ {
          # 使用zone=one的限频规则
          limit_req zone=one burst=5;
          # limit_req zone=zone2 burst=5 nodelay; # 使用
        }
    }
    

    详细解释

    限频规则定义时,可以使用内置变量$binary_remote_addr或者自定义变量。

    比如,此次使用了$binary_remote_addr ( $binary_remote_addr据各资料解释,是$remote_addr的二进制描述形式,即字符串"10.0.12.1"的整数形式表示的IP地址,使用此值,将会降低单个ip的内存占用,能够统计更多的ip请求)。

    如果,希望根据其它类条件做限速,比如 $user_agent等。

    $realip_remote_addr
    $remote_addr
    $remote_user
    

    内置变量列表 http://nginx.org/en/docs/varindex.html

    使用自定义变量

    正常情况下,我们的服务一般前面还有一层防护盾,或者其它四层的lvs/haproxy等代理,直接使用$remote_addr / $binary_remote_addr会取到负载均衡器或者盾的地址,导致本来应该针对实际用户IP的限速,变成针对整体盾的限速。

    创宇盾

    创宇盾会传递X-Connecting-Ip并设置其为收到的第一个层级请求的IP地址。

    http://help.yunaq.com/faq/67/index.html

    为方便使用,可以通过map指令将其记录到自定义变量中$clientRealIp

    map $http_x_connecting_ip $clientRealIp {
        default                     $remote_addr;
        "~(d+.d+.d+.d+)"     $1;
    }
    

    然后限频定义时,直接引用即可。

    limit_req_zone $clientRealIp zone=zoneA:32m rate=30r/m;
    limit_req_zone $clientRealIp zone=zoneB:32m rate=6r/m;
    
    # levels info | notice | warn | error; default error
    limit_req_log_level notice;
    

    最终,在location中进行限频保护。

    server {
      location *~ ^/view/ {
        limite_req zone=zoneA nodelay;
        if ( $limit_req_status = REJECTED ) {
          default_type text/plain;
          return 419 "frequency limit";
        }
        proxy_pass http://1.1.1.1:8090;
      }
    
      location *~ ^/api/v1/ {
        limit_req zone=zoneB burst=3 nodelay;
        if ( $limit_req_status = REJECTED ) {
          default_type application/json;
          return 200 '{"code":419, "status":"failed","message":"频繁访问"}';
        }
        proxy_pass http://1.1.1.1:8090;
      }
    }
    

    限速

    ...

    限并发

    ...

    自定义错误码和错误页

    ...

    其它

    nginx location/map 正则、map调测工具

    docker run -p8080:80 -d --name nginx-regex-tester ruanzx/nginx-regex-tester
    
  • 相关阅读:
    webstrom 内存溢出,软件崩溃卡死解决的方法
    JAVA 基础 / 第八课:面向对象 / JAVA类的方法与实例方法
    JAVA 基础 /第七课: 面向对象 / JAVA类的属性,类变量与实例变量
    JAVA 基础 /第六课: 面向对象 / JAVA中的类和对象
    JAVA 基础 /第五课:ECLIPSE常见的使用技巧以及部分快捷键
    JAVA 基础 / 第四课:在ECLIPSE中运行第一个 JAVA 程序以及找不到类的问题
    JAVA 基础 /第三课:下载 ECLIPSE并使用ECIPSE创建第一个 JAVA PROJECT
    JAVA 基础 / 第二课:用命令行中编写第一个 JAVA 程序
    JAVA 基础 / 第一课:手把手教你做JDK环境变量配置
    Java swing中的keyListener使用事例
  • 原文地址:https://www.cnblogs.com/morya/p/12079581.html
Copyright © 2020-2023  润新知