导读:本期聚焦于零壳创作的《Nginx ngx_stream_limit_conn_module流连接限制如何配置和使用?》,敬请观看详情。Nginx处理四层转发时如果不对并发连接数做限制,单个IP或整个服务都可能被大量连接拖垮。ngx_stream_limit_conn_module正是Nginx官方提供的四层流控模块,它按照预设的键值统计并发连接数,一旦超过设定阈值就拒绝新连接。本文将围绕这个模块展开,先讲解limit_conn_zone指令如何定义共享内存区和连接计数键,再通过完整的nginx.conf配置示例演示按客户端IP限制连接的写法,同时介绍limit_conn指令的参数含义、连接数超限时的处理行为,以及limit_conn_log_level和limit_conn_dry_run等辅助指令的用法。文中还会对比按IP限制与按整个服务器限制的差异,分析该模块与HTTP层limit_conn模块的区别,并给出常见问题的排查思路,帮助你在TCP UDP代理场景下构建稳定的连接数控制策略。

Nginx不仅是最流行的Web服务器和反向代理,在四层(传输层)代理场景中也扮演着重要角色。当Nginx被用作TCP/UDP负载均衡器时,如果放任客户端无限制地建立连接,后端服务很容易被突发的连接洪流压垮。ngx_stream_limit_conn_module就是为解决这一问题而生的官方模块,它可以在stream上下文中按照指定键值统计并发连接数,超过阈值后直接拒绝新连接。本文将从模块原理、配置指令、实战示例和常见问题几个方面,详细讲解这个模块的使用方法。

Nginx ngx_stream_limit_conn_module流连接限制如何配置和使用?

一、模块原理与编译前提

ngx_stream_limit_conn_module的定位是四层版本的连接限制器,与HTTP层的limit_conn模块思路一致,但作用对象是TCP或UDP会话而非HTTP请求。它的工作原理是在共享内存中维护一张连接计数表,每当有新连接建立时,模块会根据配置的键(通常是客户端IP)在表中查找对应的计数器并加一;当连接关闭时计数器减一。如果某个键的计数器已经达到limit_conn设定的上限,新连接会被立刻关闭,不会转发到后端服务器。

需要特别注意的是,这个模块从Nginx 1.9.x版本开始提供,并且默认情况下不会被编译进Nginx,需要在使用configure脚本构建时显式加上--with-stream_limit_conn_module参数。不过在大多数主流发行版的官方仓库或常用第三方仓库中,带stream功能的Nginx包通常已经包含该模块,可以通过nginx -V命令查看编译参数来确认。如果编译参数中没有该模块,就需要自行编译安装。

该模块的配置指令必须放在stream块中,不能放在http块里,这是初学者最常犯的错误之一。如果你的配置文件里没有stream块,需要先确保Nginx支持stream功能(编译时开启--with-stream),再进行相关配置。

二、核心指令详解:limit_conn_zone与limit_conn

limit_conn_zone用于定义连接计数所需的共享内存区和计键方式,它接受两个参数:第一个是键表达式,第二个是大小参数。键表达式最常用的写法是$remote_addr,表示按客户端IP地址统计连接数。如果想按网段统计,可以配合geo模块生成的变量使用;如果客户端经过了前置代理,也可以使用$proxy_protocol_addr获取真实来源地址。

# 在stream块中定义共享内存区,命名为addr,分配10MB内存
# 按 $remote_addr(客户端IP)作为计数键
stream {
    limit_conn_zone $remote_addr zone=addr:10m;

    server {
        listen 3306;
        proxy_pass mysql_backend;

        # 限制每个客户端IP最多同时建立20个连接
        limit_conn addr 20;
    }
}

limit_conn指令则是真正生效的限制动作,第一个参数引用limit_conn_zone定义的zone名称,第二个参数是允许的最大并发连接数。当某个键的连接数达到这个数值后,后续的新连接会被Nginx直接关闭,客户端通常表现为连接被重置或立即断开。共享内存区的大小决定了能跟踪多少个不同的键,10MB大约可以记录几十万个IP(不含IPv6的情况下每个条目占用约32到64字节),对绝大多数场景绰绰有余。如果内存区耗尽,Nginx会在错误日志中记录相应信息,并对后续请求直接拒绝。

除了按IP限制,还可以按整个虚拟服务器限制总连接数,写法是将键固定为一个常量值:

stream {
    # 定义一个固定键,用于统计整个server的连接总数
    limit_conn_zone $binary_remote_addr zone=perip:10m;

    server {
        listen 5432;
        proxy_pass pg_backend;

        limit_conn perip 10;
    }

    server {
        listen 6379;
        proxy_pass redis_backend;

        # 键恒为1,相当于限制该server总连接数不超过5000
        limit_conn_zone 1 zone=simulated:10m;
        limit_conn simulated 5000;
    }
}

三、辅助指令与调试技巧

模块还提供了几个辅助指令,在实际运维中非常实用。limit_conn_log_level用于设置连接被拒绝时日志的级别,默认是error,可以调整为notice或info,方便在排查时快速定位被限流的连接:

stream {
    limit_conn_zone $remote_addr zone=addr:10m;

    server {
        listen 3306;
        proxy_pass mysql_backend;
        limit_conn addr 20;
        # 连接超限时以notice级别记录日志
        limit_conn_log_level notice;
    }
}

limit_conn_dry_run是另一个非常有用的指令,开启后模块进入演练模式:所有超限的连接不会被真正拒绝,只会在日志中记录本来会被拒绝的信息。这个功能非常适合在上线限流策略之前观察影响范围,避免误伤正常用户。可以先开启dry_run运行几天,分析日志确认阈值合理后再切换到真实生效模式。

此外,模块还内置了$limit_conn_status变量,值为rejected或passed,可以在日志格式中引用它来精确统计被拒绝的连接数量,为容量规划提供数据支撑。建议在stream的log_format中显式输出这个变量,配合日志分析工具就能得到限流命中率的趋势图。

四、与HTTP层限流的区别及常见问题

不少刚接触Nginx四层代理的人容易混淆ngx_stream_limit_conn_module和ngx_http_limit_conn_module。两者的指令名称几乎相同,但有本质区别:HTTP层的模块工作在七层,统计的是并发HTTP请求数,键通常用$binary_remote_addr$server_name;而stream层的模块工作在四层,统计的是TCP会话或UDP会话数,面向的是数据库、消息队列、游戏服务器等长连接场景。两者不能混用,把limit_conn指令写在http块或把stream的指令写在http块都会导致配置报错。

常见的坑还有以下几点:第一,UDP场景下的连接计数以会话超时为准,Nginx会按照proxy_timeout来判定UDP会话结束,如果超时设置过长,计数器释放会明显滞后,需要合理权衡;第二,如果Nginx前面还有LVS或四层负载均衡器,$remote_addr拿到的是负载均衡器的IP,所有客户端会被算成同一个键,这时必须改用PROXY Protocol并使用$proxy_protocol_addr作为键;第三,limit_conn的数值不是越大越好,要结合后端服务的承载能力和单个连接的资源消耗来估算,配合dry_run模式逐步收敛。

总的来说,ngx_stream_limit_conn_module配置简单、开销极低,是四层代理场景下保护后端服务的第一道防线。掌握好zone定义、键的选择和阈值调优这三个要点,再结合日志观察持续优化,就能让Nginx在TCP/UDP代理场景中既保持高吞吐又具备良好的自我保护能力。

Nginxngx_stream_limit_conn_module流连接限制修改时间:2026-09-02 06:34:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。