場景要求
客戶端調用服務器a.php接口,須要執行一個長達5s-20s不等的耗資源操做,可是客戶端響應請求時間爲5秒(微信公衆帳號服務器請求響應超時時間),5s以上無回覆即斷開鏈接。php
解決設想
客戶端調用a.php以後,a.php執行異步多線程操做調用b.php,a.php調用成功後即刻反饋給客戶端回執,b.php自動執行耗資源操做。html
難點
PHP沒有真正實現多線程操做的方法。因此須要經過其它手段來進行模擬多線程。nginx
方案一
利用CURL非阻塞調用b.php,實現過程能夠參考
http://blog.csdn.net/linvo/article/details/5956629
可是有一個問題,就是a.php會繼續等待b.php的響應。
因而臨時想了一個解決方案:
在此處代碼中,將$curlopt_timeout改成1
- public $curlopt_timeout = 1;
- private $param = array();
可是這樣作就違背了curl自己的邏輯限制。
方案二
利用socket
在a.php中加入如下代碼
- $fp = fsockopen("test.com", 80, $errno, $errstr, 30);
- if (!$fp){
- echo 'error fsockopen';
- }
- else{
- stream_set_blocking($fp,0);
- $http = "GET /test/b.php HTTP/1.1\r\n";
- $http .= "Host: test.com\r\n";
- $http .= "Connection: Close\r\n\r\n";
- fwrite($fp,$http);
- fclose($fp);
- }
便可實現a.php調用b.php無阻塞。
代碼中stream_set_blocking函數用來設定socket連接爲無阻塞方式(默認爲阻塞)。
問題
在使用方案二之後,遇到了一個問題,即客戶端短期內屢次調用a.php,出現部分請求 沒有執行b.php 的狀況。
解決方法:
在Nginx的nginx.conf文件中,查看worker_processes爲1,判斷服務端響應請求的線程啓動限制太大,得知服務器自己配置爲雙核CPU,判斷2-4線程比較合適,因而修改worker_processes爲4.問題獲得解決!