场景要求
客户端调用服务器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.问题获得解决!