直接在Nginx FastCGI转发环节对敏感PHP接口限流并自动降级,是最前置有效的PHP-FPM保护方式:通过limit_req_zone按路径(如/login.php、/api/v1/order)定义独立限流区,location中启用burst/nodelay,配合proxy_intercept_errors与error_page 500-504指向@php_fallback返回预设JSON,实现毫秒级兜底,同时禁用PHP-FPM公网监听并封禁9000端口以防绕过。

直接在 Nginx 的 FastCGI 转发环节对敏感接口限流,是保护 PHP-FPM 进程最前置、最有效的方式。它不依赖 PHP 代码,也不增加后端负担,所有控制都在请求进入 FPM 之前完成。
按路径定义独立限流区域
不同接口风险和承载力差异大,不能共用一套规则。比如 /login.php 和 /api/v1/order 应单独设防:
- 在
http块中定义多个限流区,例如:limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;limit_req_zone $binary_remote_addr zone=order_limit:10m rate=20r/s; - 使用
$binary_remote_addr节省内存,10m 约支持 16 万个 IP 状态 - 登录类接口建议用
r/s单位(如 1r/s),验证码类可用r/m(如 1r/m)
在 location 中精准启用限流
只对真正走 FastCGI 的 PHP 接口生效,避免误伤静态资源或非 PHP 路径:
- 匹配敏感路径时,用精确 location 或正则,例如:
location = /login.php { limit_req zone=login_limit burst=3 nodelay; fastcgi_pass unix:/run/php/php-fpm.sock; } -
burst=3允许短时突发(如表单重试),nodelay表示超出立即拒绝,不排队 - 务必确保该 location 内没有遗漏
fastcgi_pass,否则限流无效
配合错误拦截实现自动降级
限流只是第一步;当 PHP-FPM 已响应迟缓或崩溃时,Nginx 需快速兜底,避免请求堆积雪崩:
- 开启错误拦截:
proxy_intercept_errors on;(对 FastCGI 同样生效) - 绑定常见错误码到降级入口:
error_page 500 502 503 504 = @php_fallback; - 配置内部降级响应:
location @php_fallback { internal; return 200 '{"code":429,"msg":"服务繁忙,请稍后再试"}'; } - 这样,FPM 超时、挂死或返回 5xx 时,Nginx 毫秒级返回 JSON,不重试、不转发
强化 FastCGI 隔离,防止限流被绕过
限流再严,若 FastCGI 本身可被直连,就形同虚设。必须确保 PHP-FPM 只对 Nginx 可见:
- PHP-FPM 配置中禁用公网监听:
listen = /run/php/php-fpm.sock(推荐)或listen = 127.0.0.1:9000,且listen.allowed_clients = 127.0.0.1 - 系统防火墙封死 9000 端口:
iptables -A INPUT -p tcp --dport 9000 -j DROP - Nginx 中明确使用套接字:
fastcgi_pass unix:/run/php/php-fpm.sock;,不传敏感变量如REMOTE_ADDR











