多线程 curl 无法处理大量并发 URL


Multi-threaded Curl Can't Handle Large Number of Concurrent URLs?

我必须同时调用大量API。我正在尝试通过多线程 curl 执行此操作,但似乎它无法正确获取所有 API 结果(一些错误;我认为它超时了???)如果我传递很多 URL。一次 50 个 URL 似乎是我可以通过的最大值,而一次大约 100 个是我真正开始看到问题的时候。因此,我不得不实现逻辑来对我尝试在给定时间卷曲的 URL 进行分块。

问题:

  1. 什么可能导致我的卷发问题?
  2. curl 中是否有我可以设置的内容来告诉它等待更长的响应 - 以防我的问题与超时有关?
  3. 我的服务器/php中是否有某些内容.ini我可以配置以提高脚本的性能?

下面是脚本:

function multithreaded_curl(array $urls, $concurrent_urls = 50)
    {
        // Data to be returned
        $total_results = array();
        // Chunk the URLs
        $chunked_urls = array_chunk($urls, $concurrent_urls);
        foreach ($chunked_urls as $chunked_url) {
            // Chunked results
            $results = array();
            // Array of cURL handles
            $curl_handles = array();
            // Multi-handle
            $mh = curl_multi_init();
            // Loop through $chunked_urls and create curl handles, then add them to the multi-handle
            foreach ($chunked_url as $k => $v) {
                $curl_handles[$k] = curl_init();
                curl_setopt($curl_handles[$k], CURLOPT_URL, $v);
                curl_setopt($curl_handles[$k], CURLOPT_HEADER, 0);
                curl_setopt($curl_handles[$k], CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($curl_handles[$k], CURLOPT_SSL_VERIFYPEER, 0);
                curl_multi_add_handle($mh, $curl_handles[$k]);
            }
            // Execute the handles
            $running = NULL;
            do {
                curl_multi_exec($mh, $running);
            } while ($running > 0);
            // Get content and remove handles
            foreach ($curl_handles as $k => $v) {
                $results[$k] = json_decode(curl_multi_getcontent($v), TRUE);
                curl_multi_remove_handle($mh, $v);
            }
            // All done
            curl_multi_close($mh);
            // Combine results
            $total_results = array_merge($total_results, $results);
        }
        return $total_results;
    }

关于Q1:如前所述,有几种选择可以解决该算法节奏的问题。首先,它可能会耗尽本地(句柄等)以及远程(maxConnections,maxThreads等)资源。不要那样做。

关于问题2:您不需要(见下文),但在猜测错误之前,请先获得错误响应。

关于问题 3:是的,根据远程 Web 服务器的供应商,远程 Web 服务器有几个选项(线程数限制、最大连接数、每个客户端的最大连接数等)。如果这也是你的服务器,你可以调整这些以更好地满足你的需求,但首先你应该调整客户端算法。

总体而言,一次启动多个连接没有多大意义。连接重用速度要快得多,不会破坏本地句柄等,也不会对远程系统进行DOS攻击。这样做的唯一原因是服务器需要比 io 需要的时间长得多的请求处理时间。

当您一次检查 4 个连接并

重用它们而不是创建新连接时,您是否检查了速度?实际上,您正在填充 curl_handles[] 以使用每个。创建 IO 对象需要时间。