2016-02-21 32 views
5

Tôi phải gọi đồng thời một số lượng lớn các API. Tôi đang cố gắng để làm điều này thông qua curl đa luồng, nhưng nó có vẻ như nó không có được tất cả các kết quả API đúng (một số lỗi ra, tôi nghĩ rằng nó là thời gian ra ???) nếu tôi vượt qua nó rất nhiều URL . 50 URL tại một thời điểm dường như là tối đa tôi có thể vượt qua nó, và khoảng 100 tại một thời điểm là khi tôi thực sự bắt đầu nhìn thấy vấn đề. Bởi vì điều này, tôi đã phải thực hiện logic để chunk các URL tôi cố gắng để cuộn tròn tại một thời điểm nhất định.Curl đa luồng không thể xử lý số lượng lớn các URL đồng thời?

Câu hỏi:

  1. Điều gì có thể gây ra vấn đề curl của tôi?
  2. Có điều gì đó ở dạng cuộn tròn mà tôi có thể đặt để cho nó chờ đợi lâu hơn cho phản hồi - trong trường hợp các sự cố của tôi có liên quan đến hết thời gian chờ không?
  3. Có điều gì đó trong máy chủ/php.ini của tôi có thể định cấu hình để cải thiện hiệu suất của tập lệnh của tôi không?

Đây là kịch bản:

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 - nó không phải là đa luồng 2 - nó có lẽ là một thời gian chờ PHP bạn đạt được, không phải là giới hạn thực tế curl –

+0

1. không phải là 'curl_multi_exec' đa luồng? 2. Tôi có 'set_time_limit (0);' được thực hiện trước khi gọi hàm này. – StackOverflowNewbie

+0

Golang sẽ hữu ích ở đây: D dễ dàng đồng thời. – Lansana

Trả lời

4

về Q1: Như đã nhận xét, có một số tùy chọn để có được vấn đề với algorhythm đó. Trước hết là nó có thể exhausts địa phương (xử lý vv) cũng như từ xa (maxConnections, maxThreads vv) ressources. Đừng làm theo cách đó.

liên quan đến Q2: bạn không cần phải (xem bên dưới), nhưng vui lòng nhận phản hồi lỗi trước khi đoán lỗi.

liên quan đến Q3: có, có một số tùy chọn tại máy chủ web REMOTE tùy thuộc vào nhà cung cấp máy chủ web từ xa (giới hạn số chuỗi, số kết nối tối đa, số lượng tối đa cho mỗi khách hàng, v.v.). Nếu đây cũng là máy chủ của bạn, bạn có thể điều chỉnh chúng để đáp ứng tốt hơn nhu cầu của bạn, nhưng trước tiên bạn nên điều chỉnh algorhythm của khách hàng.

Nhìn chung, bạn không nên bắt đầu nhiều hơn một số kết nối cùng một lúc. Kết nối reusage là nhanh hơn nhiều và không làm hỏng xử lý địa phương của bạn vv và không làm các cuộc tấn công DOS để hệ thống từ xa. Nguyên nhân duy nhất để làm điều này sẽ là máy chủ cần nhiều thời gian để xử lý yêu cầu của nó so với nhu cầu io.

Bạn đã kiểm tra tốc độ khi bạn chỉ cần nói 4 kết nối cùng một lúc và sử dụng lại chúng thay vì tạo các kết nối mới? Thật vậy, bạn đang cư trú curl_handles [] cho mỗi lần sử dụng. Tạo đối tượng IO tốn thời gian.

Các vấn đề liên quan