一次线上 502 排查:PHP-FPM 进程耗尽

Cold 发布于 2022-07-19 8 次阅读 314 字 预计阅读时间: 1 分钟 后端开发


晚上八点多,监控报警:接口大量 502。Nginx 错误日志里刷屏:

connect() to unix:/run/php-fpm/www.sock failed (11: Resource temporarily unavailable) while connecting to upstream

这个报错基本就是 PHP-FPM 的进程池被打满了,没有空闲 worker 处理新请求。

排查步骤

  1. ps aux | grep php-fpm | wc -l 看进程数,果然到了 pm.max_children 上限
  2. 看 FPM slow log,找到执行时间长的脚本
  3. 发现有个导出接口,一次查几万条数据,单个请求跑几十秒
  4. 几个用户同时点导出,worker 全被占满

临时处理

# 重启 fpm 释放进程(会短暂中断,谨慎)
systemctl reload php-fpm

# 调大进程数(治标)
pm.max_children = 50
pm.max_requests = 500

根治

  • 导出改异步:提交任务 → 队列处理 → 生成文件后通知下载
  • 加超时:request_terminate_timeout = 60s,避免脚本无限跑
  • 接口限流,导出类接口单独限
  • 慢日志持续监控,别等爆了才发现

FPM 配置经验值

pm = dynamic
pm.max_children = 内存 / 单进程平均内存
pm.start_servers = max_children / 4
pm.min_spare_servers = max_children / 4
pm.max_spare_servers = max_children / 2
pm.max_requests = 500  ; 防内存泄漏

502 不一定是 Nginx 的问题,先看 upstream 是谁,再顺着查。

和喜欢的一切在一起~
最后更新于 2022-07-19