2016-02-21 22 views
5

多数のAPIを同時に呼び出す必要があります。私はマルチスレッドのカールでこれをやろうとしていますが、URLの多くを渡すと、すべてのAPI結果を正しく取得できないようです(いくつかのエラーが出ます; 。一度に50のURLは私がそれを渡すことができる最大のようであり、一度に約100は私が本当に問題を見始めるときです。このため、私は一定の時間にカールしようとするURLをチャンクするロジックを実装しなければなりませんでした。マルチスレッドCurlは多数の同時URLを処理できませんか?

質問:

  1. 私のカールの問題を引き起こしている可能性がありますか?
  2. 何か問題がありますか?私の問題にタイムアウトと何か関係がある場合に備えて、応答がより長く待つように設定することができます。
  3. サーバ/ php.iniに何かありますかスクリプトのパフォーマンスを向上させるように設定できますか?ここで

はスクリプトです: Q1に関する

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

1 - マルチスレッドではありません2 - 実際のカール制限ではなく、おそらくPHPタイムアウトです。 –

+0

1. curl_multi_execマルチスレッドではありませんか? 2.この関数を呼び出す前に 'set_time_limit(0);'を実行しました。 – StackOverflowNewbie

+0

ここではGolangが役立ちます:簡単な並行性。 – Lansana

答えて

4

:既にコメントとして、そのalgorhythmの問題を取得するためのいくつかのオプションがあります。まず、ローカル(ハンドルなど)とリモート(maxConnections、maxThreadsなど)のリソースを使い果たしている可能性があります。そうしないでください。

についてQ2:あなたは(下記参照)必要はありませんが、エラーを推測する前にエラー応答を取得してください。

についてQ3:はい、リモートウェブサーバーのベンダー(スレッド番号、最大接続数、クライアントあたりの最大接続数などの制限)によって、REMOTE Webサーバーにいくつかのオプションがあります。これもあなたのサーバであれば、これらをあなたのニーズに合わせて調整することができますが、まずクライアントのアルゴリズムを調整する必要があります。

全体として、一度にいくつかの接続以上の接続を開始するのは、意味がありません。接続の再利用ははるかに高速でローカルハンドルなどを損なうことはなく、リモートシステムへのDOS攻撃は行いません。これを行うための唯一の理由は、サーバーが要求処理よりもずっと時間がかかることです。

一度に4つの接続をして、新しい接続を作成する代わりに再接続するだけの速度を確認しましたか?実際には、curl_handles []をそれぞれ1回使用するために配置しています。 IOオブジェクトの作成には時間がかかります。

関連する問題