Nginx通过分层协同实现FastCGI限流、熔断与缓存兜底:用limit_req限流防压垮PHP-FPM,max_fails+fail_timeout熔断异常实例,fastcgi_cache_use_stale兜底5xx返回旧页面,三者递进协作无需改PHP代码。
FastCGI 本身不处理限流和降级,但 Nginx 可通过 分层协同,让 FastCGI(如 PHP-FPM)在流量激增或后端异常时,仍保持页面可访问、关键路径不雪崩。核心是把限流、熔断、缓存兜底三者串成一条链路,全部落在 Nginx 配置层,无需改 PHP 代码。
用 limit_req 控制入口流量,防压垮 PHP-FPM
PHP 应用通常资源消耗高、响应慢,一旦并发突增,容易触发进程耗尽或超时。应在 Nginx 入口处按 IP 或 URI 限速:
- 定义限流区:limit_req_zone $binary_remote_addr zone=php_limit:10m rate=10r/s;
- 对动态接口启用限流:location ~ .php$ { limit_req zone=php_limit burst=20 nodelay; ... }
- 配合 limit_req_status 429 返回标准限流响应,前端可识别重试逻辑
用 max_fails + fail_timeout 实现 PHP-FPM 熔断
当某台 PHP-FPM 实例卡死、崩溃或响应超时,Nginx 要快速隔离它,避免持续转发请求:
- 在 upstream 中配置:upstream php_backend { server 127.0.0.1:9000 max_fails=3 fail_timeout=15s; }
- 启用失败重试与判定:fastcgi_next_upstream error timeout http_500 http_502 http_503 http_504;
- 失败计数达阈值后,该 PHP 实例被标记为 down,15 秒内不再分发请求
用 fastcgi_cache_use_stale 实现“过期但可用”的兜底
当所有 PHP-FPM 都不可用时,用户不该看到 502/504,而应看到一个稍旧但结构完整的页面:
- 必须提前缓存 5xx 响应:fastcgi_cache_valid 500 502 503 504 30s;
- 启用 stale 触发条件:fastcgi_cache_use_stale error timeout http_500 http_502 http_503 http_504;
- 确保 key 稳定(剔除 Cookie、时间戳等):fastcgi_cache_key "$scheme$request_method$host$request_uri";
- 敏感请求跳过缓存:fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache;(配合 if 判断登录态或后台路径)
组合使用:让降级有层次、有边界
这三者不是独立开关,而是递进关系:
- 正常流量 → 走限流控制,保 PHP-FPM 不过载
- 单点故障 → 熔断机制自动踢出坏节点,剩余节点继续服务
- 全集群不可用 → stale 缓存生效,返回最近一次成功生成的 HTML 页面
- 整个链路无依赖外部组件(如 Redis/Lua),部署简单、故障面小