Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

限流

要用到 ngx_http_limit_req_module 模块,默认安装有

  • 指定限流规则

    limit_req_zone $binary_remote_addr zone=limiter_one:20m rate=20r/s;
    
    • 参数解释
      • limit_req_zone
        • 这是一条限流规则
      • $binary_remote_addr
        • 二进制存储的 用户IP
        • 注意
          • 如果配置了CDN,那对CDN的IP限流就不对了
          • 这时就必须要获取 真正的用户原始IP $http_x_forwarded_for
          map $http_x_forwarded_for $clientRealIp {  
              "" $remote_addr;
              ~^(?P<firstAddr>[0-9\.]+),?.*$$firstAddr;
          }
          limit_req_zone $clientRealIp zone=limiter_one:20m rate=20r/s;
          
      • zone=limiter_one
        • 指定了规则的名称,叫做limiter_one
      • :20m
        • 代表存储桶大小为20MB
        • 预估 1M 可以储存 32000 个并发会话
      • rate=20r/s
        • 代表每秒钟只允许处理20个连接,超出的会被放入后面的burst
  • 使用限流规则

    server {
        
        location / {
            limit_req zone=limiter_one burst=30;
            proxy_pass http://backend_hosts;
        }
    }
    
    • 参数解释
      • limit_req
        • 对路由进行限流
      • zone=limiter_one
        • 使用上面定义的名为limiter_one的规则
      • burst
        • 缓冲队列长度
        • 例子:上面设置每秒最多20个连接
          • 如果每秒来30个,那就有10个被塞进队列中,表示可以处理(但要等待)
            • 如果后面没有连接,那这10个也会被得到处理
            • 如果后面一直都是每秒来30个,那3秒钟队列就会被塞爆,除非队列被处理出空间,否则后面一律返回503错误码,表示无法处理
      • 可选nodelay
        • 就算用户请求每秒突然暴涨超过20个,有的被塞进队列中,也会被立刻处理(不用等待),只是占了burst的坑位,保证不被恶意冲击服务器资源