PHP使用curl_multi调用API时CURLMOPT_MAX_CONNECTION不生效问题求助
问题根因排查
- 参数设置位置错误:所有
CURLMOPT_*前缀的配置都是curl_multi全局句柄的专属参数,你使用curl_setopt给单个curl请求句柄设置完全不会生效,必须用curl_multi_setopt给multi句柄设置才会生效。 - 参数名拼写错误:正确的连接数限制参数是
CURLMOPT_MAXCONNECTS,你代码中写的CURLMOPT_MAX_CONNECTION是不存在的常量,PHP会将其识别为普通字符串,配置自然不生效。 - 并发控制逻辑错误:就算正确配置了全局参数,你当前一次性把所有请求全部添加到multi句柄的逻辑也会导致curl尝试同时发起所有请求,
CURLMOPT_MAXCONNECTS仅控制curl内部的连接缓存数,不会限制实际发起的并发请求量,必须分批添加请求才能严格控制并发数不超过阈值。 - 单请求返回500排查方向:检查单请求是否缺失UA、Content-Type等第三方API要求的请求头,抓包对比单请求和并发请求的报文差异,确认请求方法、认证信息是否完全符合接口要求。
修正后的参考代码
// 初始化multi句柄 $multi = curl_multi_init(); // 全局设置最大连接数 curl_multi_setopt($multi, CURLMOPT_MAXCONNECTS, 4); $allUrls = []; $batchSize = 4; // 每批并发4个,低于接口限制的5个 $handler = fopen($filename, 'a'); // 替换为你自己的文件初始化逻辑 // 先收集所有待请求的URL foreach ($productReport2['rows'] as $productReports) { $allUrls[] = $productReports['meta']['href']; } $total = count($allUrls); $currentOffset = 0; // 分批执行请求 while ($currentOffset < $total) { $handles = []; // 单次最多添加4个请求到队列 for ($i = 0; $i < $batchSize && $currentOffset < $total; $i++, $currentOffset++) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $allUrls[$currentOffset]); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERPWD, $login); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_TIMEOUT, 15); // 增加超时避免请求卡住 curl_multi_add_handle($multi, $ch); $handles[] = $ch; } // 执行当前批次 $active = null; do { $mrc = curl_multi_exec($multi, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK) { if (curl_multi_select($multi) == -1) { usleep(1000); // 调整为1毫秒休眠,降低CPU占用 } do { $mrc = curl_multi_exec($multi, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } // 处理当前批次返回结果 foreach ($handles as $ch) { $response = curl_multi_getcontent($ch); fwrite($handler, $response); curl_multi_remove_handle($multi, $ch); curl_close($ch); } } fclose($handler); curl_multi_close($multi);
内容的提问来源于stack exchange,提问作者john Wick
相关产品推荐
相关产品推荐

