多线程卷曲无法处理大量并发URL?

时间:2016-02-21 21:27:16

标签: php multithreading curl

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

问题:

  1. 什么可能导致我的卷曲问题?
  2. 卷曲中有什么我可以设置告诉它等待更长时间的响应 - 如果我的问题与超时有关吗?
  3. 我的server / php.ini中有什么东西我可以配置来提高我的脚本的性能吗?
  4. 以下是剧本

    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;
        }
    

1 个答案:

答案 0 :(得分:4)

关于Q1的问题:正如已经评论过的,有几种方法可以解决这种算法问题。首先,它可能耗尽本地(句柄等)以及远程(maxConnections,maxThreads等)资源。不要这样做。

关于Q2:您不需要(见下文),但请在猜测错误之前收到错误回复。

关于Q3:是的,REMOTE网络服务器有几个选项,具体取决于远程网络服务器的供应商(线程数限制,最大连接数,每个客户端的最大连接数等)。如果这也是您的服务器,您可以调整这些以更好地满足您的需求,但首先您应该调整客户端算法。

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

当你刚才让我们说4个连接并重新使用而不是创建新连接时,你是否检查了速度?实际上,您只需使用curl_handles []进行单次使用。创建IO对象需要花费时间。