그러냐

curl_multi를 이용한 병렬처리 본문

php

curl_multi를 이용한 병렬처리

관절분리 2019. 11. 11. 11:04
반응형


첨부화일은 REST용 병렬처리 샘플 소스이다.
(http://gonzalo123.com/2010/02/06/building-a-rest-client-with-asynchronous-calls-using-php-and-curl/)
 
PHP에서 시간 많이 걸리는 처리를 병렬로 실행하여 고속화 할수 있다.
PHP에는 pcntl_fork라는 프로세스를 포크할수 있는 함수가 있지만 CGI모드에서만 유효해
일반적으로 PHP를 Apache모듈로 동작시키는 환경에서는 사용할수 없다.


그외에는 system함수등을 사용하여 시스템콜로 백그라운드에서 처리시키는 경우이다.

  1. system('php -f test.php > /dev/null &');

 

curl_multi를 사용해서 병렬처리

PHP5에서 curl_multi_*라는 함수군을 사용할수 있게 되었다.
curl함수는 대상을 실행시켜(URL등으로) 출력되는 결과를 리다이렉트등의 페이지 이동없이 얻을수 있다.
PHP5에서는 이러한 처리는 병렬로 가능하게 하는 curl_multi시리즈가 추가 되었다.

이것을 이용해 API에 동시에 복수의 리퀘스트를 던져 병렬처리가 되도록 해보자

샘플

  1. <?php

  2.     header('Content-type:text/html; charset=UTF-8');

  3.  

  4.     //동시 처리시킬 URL

  5.     $url_list = array(

  6.         'http://localhost/sleep.php?pid=1',

  7.         'http://localhost/sleep.php?pid=2',

  8.         'http://localhost/sleep.php?pid=3',

  9.         'http://localhost/sleep.php?pid=4',

  10.         );

  11.  

  12.     $time = time();

  13.    

  14.     //실행

  15.     $res = fetch_multi_url($url_list);

  16.    

  17.     //결과 출력

  18.     echo '실행 결과:<pre>';

  19.     print_r($res);

  20.     echo '</pre>';

  21.    

  22.     //실행 시간

  23.     echo '--<br />time:'.(time() - $time).' sec';

  24.    

  25. /**

  26.  * fetch_multi_url

  27.  *

  28.  * @param array $url_list

  29.  * @param int $timeout

  30.  * @return array

  31.  */

  32. function fetch_multi_url( array $url_list, $timeout=0 ) {

  33.     $mh = curl_multi_init();

  34.  

  35.     foreach ($url_list as $i => $url) {

  36.         $conn[$i] = curl_init($url);

  37.         curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);

  38.         curl_setopt($conn[$i],CURLOPT_FAILONERROR,1);

  39.         curl_setopt($conn[$i],CURLOPT_FOLLOWLOCATION,1);

  40.         curl_setopt($conn[$i],CURLOPT_MAXREDIRS,3);

  41.        

  42.         //SSL증명서 무시

  43.         curl_setopt($conn[$i],CURLOPT_SSL_VERIFYPEER,false);

  44.         curl_setopt($conn[$i],CURLOPT_SSL_VERIFYHOST,false);

  45.         

  46.         //타임아웃

  47.         if ($timeout){

  48.             curl_setopt($conn[$i],CURLOPT_TIMEOUT,$timeout);

  49.         }

  50.        

  51.         curl_multi_add_handle($mh,$conn[$i]);

  52.     }

  53.    

  54.     $active = null;

  55.     do {

  56.         $mrc = curl_multi_exec($mh,$active);

  57.     } while ($mrc == CURLM_CALL_MULTI_PERFORM);

  58.    

  59.     while ($active and $mrc == CURLM_OK) {

  60.         if (curl_multi_select($mh) != -1) {

  61.             do {

  62.                 $mrc = curl_multi_exec($mh,$active);

  63.             } while ($mrc == CURLM_CALL_MULTI_PERFORM);

  64.         }

  65.     }

  66.    

  67.     if ($mrc != CURLM_OK) {

  68.         echo '읽기 에러가 발생:'.$mrc;

  69.     }

  70.    

  71.     //결과 취득

  72.     $res = array();

  73.     foreach ($url_list as $i => $url) {

  74.         if (($err = curl_error($conn[$i])) == '') {

  75.             $res[$i] = curl_multi_getcontent($conn[$i]);

  76.         } else {

  77.             echo '취득실패:'.$url_list[$i].'<br />';

  78.         }

  79.         curl_multi_remove_handle($mh,$conn[$i]);

  80.         curl_close($conn[$i]);

  81.     }

  82.     curl_multi_close($mh);

  83.    

  84.     return $res;

  85. }

sleep.php

  1. <?php

  2.     sleep(5);

  3.     echo 'pid='.$_GET['pid'];

개당 5초간 sleep
이 sleep.php를 4번 실행한다면
5초 x 4회 = 20초정도 걸릴것이다.

결과

  1. Array

  2. (

  3.     [0] => pid=1

  4.     [1] => pid=2

  5.     [2] => pid=3

  6.     [3] => pid=4

  7. )

  8.  

  9. --

  10. time:5 sec

5초만에 실행되었다.  

DNS해석처리를 병렬로 실행

실제의 IP어드레스를 호스트명으로 바꾸는 처리를 병렬로 해보았다.

중복하지 않는 IP1,000개에 대하여 php의 gethostbyaddr함수를 실행
결과
-----------------------------------
순차:124초
병력(10개):33초
-----------------------------------

시간이 많이 걸리는 때는 set_time_limit의 설정을..
ignore_user_abort를 사용하면 백그라운드 처리도 가능하다.

 

출처 : https://m.blog.naver.com/PostView.nhn?blogId=parkjy76&logNo=30147781444&proxyReferer=https%3A%2F%2Fwww.google.com%2F

반응형