You need to enable JavaScript to run this app. 如何使用PHP CURL实现多线程向同一URL发送大量请求
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP CURL实现多线程向同一URL发送大量请求

解决方案

你当前的代码是串行发送请求,每次必须等前一个请求响应完成才会发起下一个,这是耗时高的核心原因。curl_multi 完全支持同基础URL的批量请求,只需要按批次控制并发数即可,实测优化后1000次请求可压缩到10秒以内(根据网络和目标接口响应速度浮动)。

优化后的代码

<?php 

class API {

    private $url = "http://xxxxxxxxxxxxxxxx";
    // 并发数,可根据目标接口承载能力调整,建议初始设10-30
    private $concurrency = 20;
    // 单个请求超时时间,单位秒,不要设0避免无限等待
    private $timeout = 10;

    public function __construct(){

    }
    public function __destruct() {

    }   

    public function callAPI($list, $country){
        $lists = explode(",", $list);
        $data = [];
        // 分批次处理,避免并发数过高
        $batches = array_chunk($lists, $this->concurrency);
        
        foreach ($batches as $batch) {
            $mh = curl_multi_init();
            $curlHandles = [];
            
            // 批量初始化当前批次的curl句柄
            foreach ($batch as $index => $id) {
                $url = $this->url . '/' . $country . '/' . $id;
                $curl = curl_init();
                curl_setopt($curl, CURLOPT_URL, $url);
                curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
                curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($curl, CURLOPT_ENCODING, '');
                curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
                curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
                curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
                // 开启TCP连接复用,同域名请求减少握手开销
                curl_setopt($curl, CURLOPT_TCP_KEEPALIVE, 1);
                curl_setopt($curl, CURLOPT_FORBID_REUSE, 0);
                
                curl_multi_add_handle($mh, $curl);
                $curlHandles[$index] = $curl;
            }
            
            // 执行当前批次的并行请求
            $running = null;
            do {
                $status = curl_multi_exec($mh, $running);
            } while ($status === CURLM_CALL_MULTI_PERFORM || $running);
            
            // 收集当前批次的响应结果
            foreach ($curlHandles as $index => $ch) {
                $response = curl_multi_getcontent($ch);
                // 可在这里加错误判断,超时/状态码非200的话可以重试
                $data[] = $response;
                curl_multi_remove_handle($mh, $ch);
                curl_close($ch);
            }
            
            curl_multi_close($mh);
        }

        return json_encode($data);
    }
}
?>

注意事项

  • 并发数不要盲目调大,过高会触发目标接口的限流策略,反而会出现大量请求失败、响应变慢的问题,建议从10开始逐步上调,找到最优值
  • 如果需要更高的可靠性,可以新增重试逻辑:判断请求返回的状态码,如果是超时、5xx错误,将对应id加入下一批次重试,最多重试2-3次即可
  • 若目标接口支持HTTP/2,可将CURLOPT_HTTP_VERSION改为CURL_HTTP_VERSION_2_0,进一步降低请求开销

内容的提问来源于stack exchange,提问作者Ervis Hysi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 19:06:10