nginx之限流详解(请求/并发量)

 更新时间:2025年08月20日 11:09:38   作者:运维经纬(公众号)  
文章介绍Web运维中使用Nginx的limit_conn和limit_req模块限制IP连接数及请求频率,防范恶意攻击和爬虫,通过$binary_remote_addr或map模块处理代理层IP,设置503错误防止服务器过载

简述

在做日常的web运维工作中,难免会遇到服务器流量异常,负载过大等情况。

恶意攻击访问/爬虫等非正常性请求,会带来带宽的浪费,服务器压力增大,影响业务质量。

限流方案

对于这种情况, 一般可考虑通过nginx的ngx_http_limit_conn_module模块和ngx_http_limit_req_module 模块限制同一client ip的请求量和并发数来防范。

1. ngx_http_limit_conn_module模块(限制连接数[并发])

limit_conn_zone

  • 语法: limit_conn_zone $variable zone=name:size;
  • 默认值: none
  • 配置段: http

$variable定义键(键的状态中保存了当前连接数),zone=name定义区域名称,后面的limit_conn指令会用到的。

size定义各个键共享内存空间大小(当共享内存空间被耗尽,服务器将会对后续所有的请求返回 503 错误。)。

limit_conn_log_level

  • 语法:limit_conn_log_level info | notice | warn | error
  • 默认值:error
  • 配置段:http, server, location
  • 当达到最大限制连接数后,记录日志的等级。

limit_conn

  • 语法:limit_conn zone_name number
  • 默认值:none
  • 配置段:http, server, location
  • 指定每个给定键值的最大同时连接数,当超过这个数字时被返回503

limit_conn_status

  • 语法: limit_conn_status code;
  • 默认值: limit_conn_status 503;
  • 配置段: http, server, location
  • 该指定在1.3.15版本引入的。指定当超过限制时,返回的状态码。默认是503。

limit_rate

  • 语法:limit_rate rate
  • 默认值:0
  • 配置段:http, server, location, if in location

对每个连接的速率限制。参数rate的单位是字节/秒,设置为0将关闭限速。

按连接限速而不是按IP限制,因此如果某个客户端同时开启了两个连接,那么客户端的整体速率是这条指令设置值的2倍。

2. ngx_http_limit_req_module模块(限制请求数)

limit_req_zone

  • 语法: limit_req_zone $variable zone=name:size rate=rate;
  • 默认值: none
  • 配置段: http

设置一块共享内存限制域用来保存键值的状态参数,速度可以设置为每秒处理请求数和每分钟处理请求数,其值必须是整数,所以如果你需要指定每秒处理少于1个的请求,2秒处理一个请求,可以使用 “30r/m”

limit_req_log_level

  • 语法: limit_req_log_level info | notice | warn | error;
  • 默认值: limit_req_log_level error;
  • 配置段: http, server, location

设置你所希望的日志级别

limit_req_status

  • 语法: limit_req_status code;
  • 默认值: limit_req_status 503;
  • 配置段: http, server, location

limit_req

  • 语法: limit_req zone=name [burst=number] [nodelay];
  • 默认值: —
  • 配置段: http, server, location

设置对应的共享内存限制域和允许被处理的最大请求数阈值。 如果请求的频率超过了限制域配置的值,请求处理会被延迟,当被延迟的请求数超过了定义的阈值,这个请求会被终止,并返回503;nodelay:表示当超过访问次数并缓冲也满的情况下,直接放回503错误,若不设置,这些多余的请求会延迟处理 。

实际运用案例

一般情况下key使用$binary_remote_addr(建议使用)或者$remote_addr变量二者区别在于: $remote_addr变量的长度为7字节到15字节,而存储状态在32位平台中占用32字节或64字节,在64位平台中占用64字节。

$binary_remote_addr变量的长度是固定的4字节,存储状态在32位平台中占用32字节或64字节,在64位平台中占用64字节。

1M共享空间可以保存3.2万个32位的状态,1.6万个64位的状态。当恭喜内存空间被耗尽时,服务会对后续请求返回503(切记).

http{
    .........
    limit_conn_zone $binary_remote_addr zone=addr:1000m;
    limit_req_zone $binary_remote_addr zone=addrs:1000m  rate=10r/s;  #每秒请求10次
    ...........
    server{
        ......
        limit_conn  addr  10;   #限制并发数为10
        limit_req zone=addrs burst=5 nodelay;   #允许超出请求5(排队/延迟)
        ......
        }
    }
#注  limit_conn_zone 和limit_req_zone可单独使用

除以上以$binary_remote_addr变量为key外,还有一种情况,如前端使用了代理层,CDN等服务,这种情况下$binary_remote_addr变量会是代理层/CDN的ip,就无法通过$binary_remote_addr变量做限制, 目前知道有两种解决方式,一种是使用白名单, 另外一种是配置$http_x_forwarded_for然后取逗号分隔的第一个ip(即源ip,不太好的消息就是这个变量字段是可以通过修改请求head信息进行伪造(curl -H "X-Forwarded-For:192.168.0.1,192.168.0.2" http://127.0.0.1 ))。

白名单的方式后续再说。

这里先说下第二种方法, 可通过nginx的map模块做正则匹配后映射请求源ip, 具体配置如下:

1)代理层的配置:

    upstream renren_trans_1 {
        server 10.5.11.12;
    }
    server {
        listen  80;
        server_name zabbixtest.d.xiaonei.com;
        http_accounting_id  zabbixtest;
        location / {
                proxy_pass         http://renren_trans_1;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
                client_max_body_size       50m;
                client_body_buffer_size    128k;
                client_body_temp_path      /data/client_body_temp;
                proxy_connect_timeout      15;
                proxy_send_timeout         300;
                proxy_read_timeout         300;
                proxy_buffer_size          8k;
                proxy_buffers              4 32k;
                proxy_busy_buffers_size    64k;
                proxy_temp_file_write_size 64k;
                proxy_temp_path            /data/proxy_temp;
        }
    }

代理层后端(业务机)配置:

    map $http_x_forwarded_for $clientips {

        "" $remote_addr;                        #当为空时映射$remote_addr 到$clientips
        ~^(?P<firstip>[0-9\.]+),?.*$ $firstip;  #获取第一个ip
    }


    limit_conn_zone $clientips zone=addr:1000m;
    limit_req_zone $clientips zone=addrs:1000m  rate=10r/s;

    limit_req zone=addrs burst=5 nodelay;
    server {
        listen       80;
        server_name  localhost;

        limit_conn  addr  10;
        limit_req zone=addrs burst=5 nodelay;
        #charset koi8-r;

        #access_log  logs/host.access.log  main;

测试:

 1) 测试通过代理层访问的方式:

# ab -c 11 -t 10 http://zabbixtest.d.xiaonei.com/test.html

access.log内容如下:

可发现大量503 error(第一列代理层,最后一列源ip) 。

2)测试直接访问,不通过代理层

# ab -c 5 -t 10 http://10.5.11.12/test.html

access.log如下:

同样会出现大量503 ,代理ip为空!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解Nginx反向代理实现Kibana登录认证功能

    详解Nginx反向代理实现Kibana登录认证功能

    这篇文章主要介绍了详解Nginx反向代理实现Kibana登录认证功能,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • 隐藏网站Nginx版本号信息的方法分享

    隐藏网站Nginx版本号信息的方法分享

    隐藏网站nginx服务的版本号信息,在安全的角度上来说,可以防止黑客快速利用nginx的版本漏洞进行攻击,所以本文为大家整理了隐藏网站Nginx版本号信息的方法,希望对大家有所帮助
    2023-08-08
  • 详解Nginx配置文件

    详解Nginx配置文件

    Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的,Nginx功能丰富,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。这篇文章主要介绍了Nginx配置文件,需要的朋友参考下
    2017-01-01
  • Nginx日志统计分析的常用命令总结

    Nginx日志统计分析的常用命令总结

    这篇文章主要给大家总结了关于Nginx日志统计分析的一些常用命令,其中包括IP相关统计、页面访问统计、性能分析、蜘蛛抓取统计、TCP连接统计等相关命令的总结,相信对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-07-07
  • 详解Nginx服务器的nginx-http-footer-filter模块配置

    详解Nginx服务器的nginx-http-footer-filter模块配置

    这篇文章主要介绍了Nginx服务器的nginx-http-footer-filter模块配置,nginx-http-footer-filter用作在请求的页面底部插入代码,需要的朋友可以参考下
    2016-01-01
  • Nginx解决Http慢攻击(Slow HTTP Attack)的方法

    Nginx解决Http慢攻击(Slow HTTP Attack)的方法

    缓慢的HTTP拒绝服务攻击是一种专门针对于Web的应用层拒绝服务攻击,本文给大家介绍了Nginx解决Http慢攻击(Slow HTTP Attack)的方法,需要的朋友可以参考下
    2024-02-02
  • nginx proxy_redirect的作用及说明

    nginx proxy_redirect的作用及说明

    这篇文章主要介绍了nginx proxy_redirect的作用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • Linux环境下nginx搭建简易图片服务器

    Linux环境下nginx搭建简易图片服务器

    这篇文章主要介绍了Linux环境下nginx搭建简易图片服务器,需要的朋友可以参考下
    2014-10-10
  • 在Linux中查看Apache或Nginx服务状态的详细步骤

    在Linux中查看Apache或Nginx服务状态的详细步骤

    在Linux中,查看Apache或Nginx服务的状态通常涉及到使用系统管理工具或特定于这些Web服务器的命令,以下是如何查看Apache和Nginx服务状态的详细步骤,需要的朋友可以参考下
    2024-03-03
  • 如何配置nginx作为静态文件托管服务器

    如何配置nginx作为静态文件托管服务器

    这篇文章主要介绍了如何配置nginx作为静态文件托管服务器的相关资料,下载nginx在windows上是个压缩包,解压后,使用命令行输入nginx进行启动,感兴趣的朋友跟随小编一起看看吧
    2024-01-01

最新评论