HAProxy后端请求超时且服务器等待时间过长问题排查求助
这问题我之前帮几个运维朋友排查过类似的,咱们先拆解下你给出的两段日志,理清关联后再分析成因和排查方向。
日志关键信息解读
首先看HAProxy的日志字段:
Jan 31 08:22:22 localhost haproxy[4029466]: 127.0.0.1:41408 [31/Jan/2018:08:05:12.587] http-in server/myservername 0/0/4/1029610/1029615 500 569 - - CD-- 64/64/0/0/0 0/0 "POST /file.php HTTP/1.1"
这里的0/0/4/1029610/1029615是HAProxy的时间统计字段,核心问题是第四个值1029610(单位毫秒)——这是后端服务器的处理时间(Tr),足足超过17分钟,远超过正常请求的处理时长。最后返回500状态码,说明后端最终因为超时抛出了错误。
再看Apache的mod_fcgid错误:
[Wed Jan 31 08:22:22 2018] [warn] [client XXXX:XXXX::1] (70007)The timeout specified has expired: mod_fcgid: can't get data from http client, referer: XXX
这个错误看起来是mod_fcgid在等待客户端(也就是HAProxy)的数据时超时,但结合HAProxy的Tr时间来看,实际是后端PHP进程长时间阻塞,导致mod_fcgid等待PHP返回结果超时,进而触发HAProxy的后端超时等待,最终返回500。
可能的成因
PHP进程长时间阻塞:这是最常见的原因,比如:
- 数据库查询超时、死锁,或者执行了未加索引的慢SQL
- 调用外部API/服务时没有设置超时,导致一直等待响应
- 代码里出现死循环、递归调用失控
- 大文件上传/处理时,IO操作耗时远超超时阈值
- 文件锁、进程锁等待,导致进程挂起
mod_fcgid配置不合理:
FcgidIOTimeout(默认通常40秒)设置过短,正常长耗时请求被误判超时;或者设置过长,导致卡住的进程一直占用资源FcgidMaxRequestLen不足,无法处理大POST请求(比如你这里是POST /file.php,可能涉及文件上传)FcgidBusyTimeout、FcgidIdleTimeout等参数未根据业务调整,导致进程资源无法及时释放
HAProxy与后端超时不匹配:
- HAProxy的
timeout server设置得比mod_fcgid的超时更长,导致HAProxy一直等待后端,直到mod_fcgid最终抛出500,这就解释了Tr时间长达数千秒的现象
- HAProxy的
后端服务器资源瓶颈:
- 磁盘IO满负载、内存不足导致进程swap,或者CPU使用率过高,都可能让PHP进程处理变慢甚至卡住
分步排查方法
1. 定位卡住的PHP请求(最优先)
- 找出长时间运行的PHP进程:执行
ps aux | grep php,看有没有CPU/内存占用异常、运行时间极长的PID - 跟踪进程系统调用:用
strace -p <PID>跟踪这个进程,看它卡在哪个操作上——比如是在connect()等待外部服务,还是read()/write()操作磁盘,或是poll()等待数据库响应 - 开启PHP慢日志:在
php.ini里配置:
这样超过10秒的请求会被记录,能直接看到是哪段代码导致的阻塞slowlog = /var/log/php-slow.log request_slowlog_timeout = 10s
2. 检查mod_fcgid配置
打开Apache的mod_fcgid配置文件(比如/etc/apache2/mods-enabled/fcgid.conf),重点核对以下参数:
FcgidIOTimeout:如果你的业务确实有长耗时请求(比如文件处理),可以适当调高,但如果是无意义的卡住,不要盲目调大,先解决代码问题FcgidMaxRequestLen:如果是大文件上传,确保这个值大于上传文件的最大大小(比如设置为1073741824对应1GB)FcgidMaxProcessesPerClass:限制每个虚拟主机的FCGI进程数,避免卡住的进程占满所有资源FcgidIdleTimeout:设置闲置进程的超时时间,及时释放资源
3. 对齐HAProxy与后端的超时设置
编辑HAProxy配置文件,确保timeout server的设置略短于mod_fcgid的FcgidIOTimeout,比如:
backend server server myservername 192.168.x.x:80 check timeout server 35s # 比mod_fcgid的40秒短5秒,避免HAProxy无谓等待
这样后端超时后HAProxy能及时断开连接,不会出现长达数千秒的Tr时间
4. 检查后端服务器资源与依赖
- 用
top/htop查看CPU、内存、磁盘IO的实时状态,看有没有异常负载 - 查看数据库慢查询日志,排查是否有长时间运行的SQL语句
- 如果PHP调用了外部服务(比如API、Redis、MQ),检查这些服务的可用性和响应时间,确保设置了合理的超时时间
临时缓解措施
如果暂时找不到代码问题,可以先调整mod_fcgid的进程回收机制,避免卡住的进程占用过多资源:
FcgidIdleTimeout 60 FcgidProcessLifeTime 3600 FcgidMaxProcessesPerClass 10
内容的提问来源于stack exchange,提问作者holger359




