PHP/CURL执行导致Apache服务器卡顿问题求助
解决PHP CURL导致Apache服务器卡顿的问题
问题根源
当前代码使用同步阻塞的CURL请求,执行时会完全占用Apache的一个工作进程,直到CURL请求完成(最长200秒)。如果有多个并发请求,会快速耗尽Apache的进程池,导致服务器卡顿甚至无响应。
解决方案
1. 改用CURL非阻塞异步模式(即时场景首选)
使用curl_multi_*系列函数实现非阻塞请求,让Apache进程在等待CURL响应时可以处理其他请求,避免进程被长时间占用。示例代码:
$url_sh = "****"; $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 15); // 大幅缩短超时时间,建议10-30秒 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_URL, $url_sh); // 初始化多请求句柄 $mh = curl_multi_init(); curl_multi_add_handle($mh, $ch); // 非阻塞执行循环 $running = null; do { $execStatus = curl_multi_exec($mh, $running); if ($execStatus != CURLM_CALL_MULTI_PERFORM) { curl_multi_select($mh); // 释放CPU资源,避免空循环占用 } } while ($running > 0 && $execStatus == CURLM_OK); // 获取请求结果 $result = curl_multi_getcontent($ch); // 清理资源 curl_multi_remove_handle($mh, $ch); curl_multi_close($mh); curl_close($ch); $obj = json_decode($result, true); $approved_img = '<img src="'.$obj['lighthouseResult']['audits']['final-screenshot']['details']['data'].'">';
2. 缩短CURL超时时间
原代码设置的CURLOPT_TIMEOUT=200秒过长,即使是同步请求,也建议缩短到10-30秒,减少进程被占用的时长,降低卡顿风险。
3. 配置PHP-FPM替代Apache mod_php
默认的Apache mod_php会为每个请求分配独立进程,资源利用率低。改用PHP-FPM可以更好地控制进程数量、动态调整进程池,避免进程耗尽:
- 安装PHP-FPM:
apt install php7.4-fpm - 配置Apache启用proxy_fcgi模块,将PHP请求转发到FPM
- 调整PHP-FPM配置文件
/etc/php/7.4/fpm/pool.d/www.conf中的参数:pm.max_children:根据服务器内存设置,比如1核2G内存设为20-30pm.start_servers:初始启动进程数,设为max_children的1/4pm.min_spare_servers/pm.max_spare_servers:控制空闲进程数
4. 异步任务队列(非实时场景推荐)
如果不需要即时返回CURL请求结果,可将任务放入队列,用后台进程异步处理:
- 将请求参数存入Redis队列
- 编写PHP脚本循环从队列取任务执行CURL,将结果存入数据库/缓存
- 前端Ajax先返回“请求已提交”,后续通过轮询或WebSocket获取处理结果
- 用Supervisor管理后台脚本,确保进程持续运行
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

