PHP curl_multi_exec上传Etsy图片:7次正常,千次调用失败排查
问题
首次使用curl_multi_init向Etsy平台上传千余张高清图片,单循环执行超时,改用多CURL调用后出现以下问题:仅7次调用可正常执行,超过7次(含批量无限制调用)时,连前7次请求都无法连接服务器,报错CURLE_COULDNT_CONNECT;调整PHP内存限制后问题反而恶化。
已完成诊断:DNS解析正常,TCP可建立连接,但多CURL调用超7次即失败。
相关代码:
<?php include_once 'databaseStuff.php'; include_once 'EtsyTokenStuff.php'; $result = mysqli_query($conn, "SELECT product, listing_id, alt_text, dataStuff;"); $multiCurl = []; $multiResult = []; $multiHandle = curl_multi_init(); if (mysqli_num_rows($result) > 0){ while ($row = mysqli_fetch_assoc($result)){ for($image = 1; $image <=2; $image++){ $multiCurl[$row['product'] . "_" . $image] = curl_init(); curl_setopt_array($multiCurl[$row['product'] . "_" . $image], array( CURLOPT_URL => "https://openapi.etsy.com/v3/application/shops/$myShopNumber/listings/" . $row['listing_id'] . "/images", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => array( "image" => new CURLFILE( [ 1 => "img/imagePathStuff/" . $row['product'] . ".jpg", 2 => "img/differentImagePathStuff/" . $row['product'] . ".jpg" ][$image] ), // "listing_image_id" =>, "rank" => $image, "overwrite" => true, // "is_watermarked" =>, "alt_text" => $row['alt_text'] ), CURLOPT_HTTPHEADER => array( "x-api-key: $myAPIKey", "authorization: Bearer {$etsyAccessToken}" ), ) ); curl_multi_add_handle($multiHandle, $multiCurl[$row['product'] . "_" . $image]); } } $index = null; do { curl_multi_exec($multiHandle, $index); } while($index > 0); foreach($multiCurl as $k => $curlHandle){ $multiResult[$k] = curl_multi_getcontent($curlHandle); curl_multi_remove_handle($multiHandle, $curlHandle); } curl_multi_close($multiHandle); }
解决方案
- 严格控制并发连接数:Etsy服务器或API大概率存在并发请求限制,超过7个连接会被直接拦截。实现分批处理逻辑,比如每次仅发起5-7个请求,完成一批后释放资源,再处理下一批,避免一次性发起大量连接。
- 优化CURL参数配置:
- 取消
CURLOPT_TIMEOUT => 0的设置,改为30-60秒的合理超时值,避免请求无限等待占用资源;同时添加CURLOPT_CONNECTTIMEOUT设置10秒左右的连接超时,快速终止失败的连接尝试。 - 将
CURLOPT_HTTP_VERSION改为CURL_HTTP_VERSION_2TLS,利用HTTP/2的多路复用特性,用更少的连接完成更多请求,降低并发压力。
- 取消
- 及时释放资源:当前代码一次性加载所有图片并添加CURL handle,会导致内存暴涨(高清图片占用大量内存)。改为每处理完一批请求,就立即关闭对应CURL handle、释放内存,避免资源堆积——这也是调整内存限制后问题恶化的核心原因。
- 核对Etsy API限制:查阅Etsy官方文档,确认API的并发请求数、上传频率限制,严格按照规则控制请求节奏,必要时添加请求间隔。
- 开启CURL调试日志:添加
CURLOPT_VERBOSE => true并指定日志文件路径,记录连接阶段的详细交互信息,精准定位是服务器主动拒绝还是本地网络/资源问题导致的连接失败。
内容的提问来源于stack exchange,提问作者Jonathon Philip Chambers
相关产品推荐
相关产品推荐

