You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:18:24