php實現異步請求


PHP開啟異步多線程執行腳本

 裝載自:http://www.cnblogs.com/clphp/p/4913214.html

場景要求

客戶端調用服務器a.php接口,需要執行一個長達5s-20s不等的耗資源操作,但是客戶端響應請求時間為5秒(微信公眾賬號服務器請求響應超時時間),5s以上無回復即斷開連接。

解決設想

客戶端調用a.php之后,a.php執行異步多線程操作調用b.php,a.php調用成功后即刻反饋給客戶端回執,b.php自動執行耗資源操作。

難點

PHP沒有真正實現多線程操作的方法。所以需要通過其它手段來進行模擬多線程。

方案一

利用CURL非阻塞調用b.php,實現過程可以參考
http://blog.csdn.net/linvo/article/details/5956629
但是有一個問題,就是a.php會繼續等待b.php的響應。
於是臨時想了一個解決方案:
在此處代碼中,將$curlopt_timeout改為1
[php]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. /**  
  2.      * 單個CURL調用超時限制   
  3.      */    
  4.     public $curlopt_timeout = 1;    
  5.     private $param = array();    

但是這樣做就違背了curl本身的邏輯限制。
 

方案二

利用socket
在a.php中加入以下代碼
[php]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. $fp = fsockopen("test.com", 80, $errno, $errstr, 30);  
  2. if (!$fp){  
  3.     echo 'error fsockopen';  
  4. }  
  5. else{  
  6.     stream_set_blocking($fp,0);  
  7.     $http = "GET /test/b.php HTTP/1.1\r\n";      
  8.     $http .= "Host: test.com\r\n";      
  9.     $http .= "Connection: Close\r\n\r\n";  
  10.     fwrite($fp,$http);  
  11.     fclose($fp);  
  12. }  
即可實現a.php調用b.php無阻塞。
代碼中stream_set_blocking函數用來設定socket鏈接為無阻塞方式(默認為阻塞)。
 

問題

在使用方案二以后,遇到了一個問題,即客戶端短時間內多次調用a.php,出現部分請求 沒有執行b.php 的情況。
解決方法:
在Nginx的nginx.conf文件中,查看worker_processes為1,判斷服務端響應請求的線程啟動限制太大,得知服務器本身配置為雙核CPU,判斷2-4線程比較合適,於是修改worker_processes為4.問題得到解決!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM