Nginx 连接限流模块 ngx_http_limit_conn_module

欢迎大家关注本博,同时欢迎大家评论交流,可以给个赞哦!!!

  ngx_http_limit_conn_module用于限制每个已定义关键字的连接数,特别是来自单个IP地址的连接数。

​  并非所有连接都被计数,仅当连接是服务器正在处理的请求且已读取整个请求头时,才对连接进行技术。

  为什么需要限流

  限流实际是控制服务入口的流量,防止服务出现流量过载导致服务宕机等问题。

  用户数量庞大的应用,尤其是互联网应用,面对庞大的用户群体,在高并发场景下,因为请求过多,压力转移到服务器,容易导致服务宕机等故障,因此需要使用限流对服务进行保护。

  · 瞬时大量用户访问服务器,导致服务器超载而宕机。

  · 恶意请求攻击服务器,导致服务器超载而宕机。

  · 对于特定应用,例如爬虫等,针对性的进行分析、限流。

  什么是连接限流

  Http协议建立在Tcp协议之上,要建立Http连接,需要先进行Tcp三次握手,然后才能建立Http连接,在Http连接之上进行请求和响应。

  连接限流模块主要限制的就是Http连接,由于Http协议的发展,目前Http可以保持长连接,在一个连接中进行多次请求和响应,此时连接限流模块计数时,仅会把这种情况计作1,不会关心请求数量。

  连接限流模块 语法即语义

  limit_conn

   语法:limit_conn zone number;

   语义:设置共享内存区域和给定键值的最大允许连接数。当超过此限制时,服务器将返回错误响应请求。

   当且仅当limit_conn当前级别上未定义任何指令时,这些指令才从先前的配置级别继承。

  limit_conn_dry_run

   语法:limit_conn_dry_run on | off;

   语义:启用空运行模式。在此模式下,连接数不受限制,但是,在共享内存区域中,过多连接的数将照常计算。

  limit_conn_log_level

   语法:limit_conn_log_level info | notice | warn | error;

​   语义:为服务器限制连接数的情况设置所需的日志记录级别。

  limit_conn_status

   语法:limit_conn_status code;

   语义:设置状态代码以响应被拒绝的请求作为返回。

  limit_conn_zone

   语法:limit_conn_zone key zone=name:size;

   语义:设置共享内存区域的参数,该参数将保留各种键的状态。特别是,状态包括当前的连接数。该key可以包含文本,变量,他们的组合。具有空键值的请求不予考虑。

​   key:请求匹配的规则,若客户端请求匹配key,则进入zone。常用的键包括:$ binary_remote_addr(客户端地址(二进制形式),对于IPv4地址,值的长度始终为4个字节,对于IPv6地址,值的长度始终为16个字节)、$ uri(请求中的当前URI)、$ request_uri(完整的原始请求URI(带有参数))、$server_name(接受请求的服务器的名称)。

  limit_zone

   语法:limit_zone name $variable size;

   语义:该指令在1.1.8版中已过时,在1.7.6版中已删除。应当使用等效的limit_conn_zone指令。

  连接限流模块 示例

  在默认nginx.conf基础上增加limit_conn相关配置:

worker_processes  1;

error_log  logs/error.log;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;
    # $binary_remote_addr:客户端地址(二进制形式),对于IPv4地址,值的长度始终为4个字节,对于IPv6地址,值的长度始终为16个字节.
    # 定义名为'remote_addr_zone'的共享内存区域,用于针对单个客户端地址计数.
    limit_conn_zone $binary_remote_addr zone=remote_addr_zone:1m;
    # $server_name:接受请求的服务器的名称.
    limit_conn_zone $server_name zone=server_name_zone:1m;

    server {
        listen       80;
        server_name  localhost;

        location / {
	    limit_conn remote_addr_zone 1;
	    limit_conn server_name_zone 1;

            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

  接下来,使用ab(Apache Bench)进行并发压力测试,本人使用windows版本:

d:
cd K:\Service\Apache Bench\Server\httpd-2.4.41-win64-VS16\Apache24\bin
ab -n 10000 -c 100 http://192.168.20.9/index.html

  上面模拟100个客户端、10000个请求,执行之后,查看ab的统计结果如下图:
在这里插入图片描述
  需要注意的是,当-c和-n设置较小时,可能无法出现上面的情况,需要多次尝试才可以达到效果。若是希望尽快达到效果,可以根据个人机器情况,适当提高-c和-n的值。

  可以看到,ab共发送了10000个请求,其中69次非2xx响应码,此时,查看Nginx的error.log(/usr/local/nginx/logs/error.log),会发现日志中在提示下图中的信息,说明limit_conn连接限流模块开始起作用了。
在这里插入图片描述
  连接限流模块 完整配置

  上面示例中,只配置了limit_conn_zone和limit_conn指令,其他指令未做展示,下面提供连接限流模块的完整配置,具体验证,可以自行验证。

worker_processes  1;

error_log  logs/error.log;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;
    # $binary_remote_addr:客户端地址(二进制形式),对于IPv4地址,值的长度始终为4个字节,对于IPv6地址,值的长度始终为16个字节.
    # 定义名为'remote_addr_zone'的共享内存区域,用于针对单个客户端地址计数.
    limit_conn_zone $binary_remote_addr zone=remote_addr_zone:1m;
    # $server_name:接受请求的服务器的名称.
    limit_conn_zone $server_name zone=server_name_zone:1m;
    # 1.1.8版本已过时,1.7.6版本已删除,与limit_conn_zone等效.
    # limit_zone

    server {
        listen       80;
        server_name  localhost;

        location / {
	    # 指定连接限流模块日志级别.
	    limit_conn_log_level error;
	    # 指定限流时返回Http响应码.
	    limit_conn_status 503;
	    # 指定每个客户端地址并发连接数为1.
	    limit_conn remote_addr_zone 1;
	    # 指定当前服务器并发连接数为1.
	    limit_conn server_name_zone 1;
	    # 启用空运行模式。在此模式下,连接数不受限制,但是,在共享内存区域中,过多连接的数将照常计算.
	    # limit_conn_dry_run off;

            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

  虽然ngx_http_limit_conn_module提供了很多指令,但某些应用场景十分有限,在应用时使用默认值即可,没必要太纠结所有指令是否齐全。

  总结

  应用上线后,需要复制机制对应用进行长期监视和分析,若出现服务过载的情况,需要酌情分析,当代理或负载配置时,针对某些可能导致服务宕机的业务进行限流,在影响某些客户使用体验的情况下,保证绝大部分用户可以正常且无误的使用应用。

  若文中存在错误和不足,欢迎指正!

本博微信公众号“超哥说码”,欢迎大家订阅,公众号正在完善中,会及时将更优质的博文推送于您!
在这里插入图片描述

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值