批量cURL请求触发HTTP 500错误,sleep与超时调整无效
我之前做批量URL检测的时候也遇到过几乎一模一样的问题——调整max_execution_time和隔段sleep根本解决不了,后来排查下来是资源泄漏和服务器限制的锅,给你几个实际有用的排查和解决方向:
先排查内存泄漏问题
很多人用cURL的时候容易忽略关闭句柄,每次请求如果只初始化curl_init()却不调用curl_close($ch),会导致内存持续占用,300-400次请求后就会耗尽PHP的内存配额触发500错误。一定要确保每个请求完成后释放资源:$ch = curl_init($url); // 设置cURL选项... $response = curl_exec($ch); // 处理响应... curl_close($ch); // 关键!释放句柄另外可以在脚本里定期输出内存使用情况,比如每100次请求后打印
memory_get_usage(true),看看是不是内存一直在飙升。调整请求频率与并发策略
每100次请求才睡30秒的间隔太粗糙了,很多服务器(尤其是共享主机)对同一IP的每秒请求数有严格限制,短时间内密集请求会被判定为恶意访问,直接返回500。建议改成每次请求后休眠1-2秒,或者用随机间隔(比如sleep(rand(1,3))),避免触发防攻击机制。
如果追求效率,可以试试curl_multi批量处理,它能同时发起多个请求但资源占用比循环单请求低很多,不过要注意控制并发数(比如同时处理5-10个),别一下子开太多。检查PHP内存限制
max_execution_time只是控制脚本执行时长,真正可能导致崩溃的是memory_limit。如果你的脚本在执行过程中存储了所有URL的检测结果(比如存在数组里),6000条数据很容易超过默认的内存配额。可以在脚本开头手动调高内存限制:ini_set('memory_limit', '256M'); // 或者更高,比如512M同时记得及时清理没用的变量,比如处理完一个URL后就unset掉相关的临时变量。
查看服务器错误日志找根因
页面显示的HTTP 500只是表面现象,真正的错误原因在服务器的日志里——比如Apache的error.log、Nginx的error.log或者PHP的error_log。去日志里找对应的时间点,大概率能看到具体的报错信息:是内存耗尽、cURL连接失败,还是服务器的防攻击模块拦截了请求?改用分批/队列处理(终极方案)
一次性处理6000条请求本来就不符合PHP脚本的设计场景,长时间运行的脚本很容易因为各种服务器限制出问题。最好的办法是把任务拆分:- 把所有URL存入数据库,标记状态为“未检测”
- 写一个处理脚本,每次只取出100条未检测的URL处理,完成后标记为“已检测”
- 用Cron定时任务每分钟跑一次这个脚本,慢慢把所有URL处理完
这种方式既避免了资源耗尽,也能在脚本意外中断后从上次的位置继续,不会前功尽弃。
内容的提问来源于stack exchange,提问作者Dasmond

