fastcgi 本身不支持按 ip 限并发,nginx 需通过 limit_conn 模块限制发往 fastcgi 后端的并发连接数,并基于 $binary_remote_addr(或 $realip_remote_addr)按真实客户端 ip 统计;需在 http 块定义 limit_conn_zone,location 中配置 limit_conn 与 fastcgi_pass 配合生效,推荐启用 fastcgi keepalive 并调优 php-fpm 参数以提升效果。

FastCGI 本身不直接提供按 IP 限并发的能力,Nginx 对 FastCGI 的并发控制必须通过其内置的连接限流模块实现,核心是 limit_conn 配合 fastcgi_pass 的作用域控制——不是限制“FastCGI 请求”,而是限制“发往 FastCGI 后端的并发连接数”,并确保该限制按客户端真实 IP 统计。
必须在 http 块定义共享内存区
限流状态需要全局存储,limit_conn_zone 必须写在 http{} 最外层:
-
limit_conn_zone $binary_remote_addr zone=fcgi_ip:10m;—— 使用二进制 IP 节省内存,10MB 约支持 16 万独立 IP - 若经 CDN 或反向代理(如 Cloudflare、SLB),需先启用
realip_module并配置set_real_ip_from和real_ip_header X-Forwarded-For,再改用$realip_remote_addr作 key
在 location 中绑定 FastCGI 并启用限流
把 limit_conn 放在调用 fastcgi_pass 的 location 块内,才能精准作用于动态请求路径:
location ~ \.php$ {-
limit_conn fcgi_ip 3;—— 每个 IP 最多维持 3 个到 FastCGI 后端的并发连接 -
fastcgi_pass 127.0.0.1:9000;(或 unix socket) include fastcgi_params;}
注意:该限制针对的是 Nginx 与 PHP-FPM 进程间建立的 TCP 连接(或 Unix socket 连接),不是 PHP 内部的请求处理数。一个连接可复用多个 FastCGI 请求(尤其在 keepalive 开启时),但连接总数被卡死在 3 以内。
配合 FastCGI keepalive 提升效果
默认 FastCGI 连接非长连接,每次请求新建连接,max_conns 和 limit_conn 效果会打折。需显式开启后端长连接:
- 在 upstream 块中定义(推荐):
upstream php_backend {<br> server 127.0.0.1:9000;<br> keepalive 16;<br>}
然后fastcgi_pass php_backend; - 或直接用
fastcgi_keep_conn on;(Nginx 1.1.4+),但仅对单台后端有效 - PHP-FPM 配置中也要匹配:确保
pm.max_children足够,且rlimit_files不过低
增强可观测性与容错
让限流行为更可控、问题更易定位:
-
limit_conn_status 429;—— 返回标准限流码,前端可区分处理,而非默认的 503 -
limit_conn_log_level error;—— 只在真正触发限制时记日志,避免刷屏 - 搭配
limit_req防 HTTP/2 或高复用场景失效:limit_req zone=fcgi_rate burst=10 nodelay;(需提前定义limit_req_zone)











