PHP CURL超时但CLI CURL有效

时间:2012-12-11 04:29:17

标签: php curl nginx timeout

我正在看到我正在构建的PHP应用程序存在一个非常奇怪的问题。

我的开发服务器上有2个虚拟主机(Windows 7 64位)sometestsite.comendpoint.sometestsite.com

在我的hosts文件中,我将sometestsite.comendpoint.sometestsite.com配置为指向127.0.0.1

当服务器运行Apache 2.4.2,PHP 5.4.9作为fcgi模块时,一切正常。

然后我删除了Apache并安装了nginx-1.2.5(windows build)。我把php-cgi.exe作为服务运行,一切似乎都运行良好。

问题是从sometestsite.comendpoint.sometestsite.com的CURL调用之前有效会超时。

然后我将这段代码单独移动到一个小的PHP文件中进行测试:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://endpoint.sometestsite.com/test');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('provider' => urlencode('provider'),
'key' => urlencode('asdf')));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

//Execute and get the data back
$result = curl_exec($ch);

var_dump($result);

这是我在PHP日志中收到的内容:

PHP Fatal error:  Maximum execution time of 30 seconds exceeded in D:\www\test5.php on line 22
PHP Stack trace:
PHP   1. {main}() D:\www\test5.php:0

但是,如果我使用CLI CURL(通过Git Bash)运行相同的请求,它可以正常工作:

$ curl -X POST 'http://endpoint.sometestsite.com/test' -d'provider=provider&key=asdf'
{"test": "OK"}

这很奇怪,因为PHP版本完全相同,并且具有与使用Apache时相同的配置。

我不确定这是否是Web服务器配置问题或PHP的CURL问题。

任何人都可以提供一些见解/过去的经验,为何会发生这种情况?

2 个答案:

答案 0 :(得分:1)

Nginx不会为您生成php-cgi.exe进程。如果你像我一样来自Apache并使用mod_fcgid,你会发现系统中有很多php-cgi.exe进程。

因为Nginx不会为您生成PHP进程,所以您需要自己启动该进程。在我的情况下,我php-cgi.exe -b 127.0.0.1:9000自动运行作为服务。然后Nginx将所有PHP请求推送到PHP处理程序并收到响应。

问题:PHP-FPM does not work on windows(截至5.4.9)。 FPM是一个整洁的小流程管理器,它处于后台并管理处理请求时产生和杀死PHP进程。

由于这是不可能的,因此在Windows上,我们一次只能提供1个请求,类似于problem experienced here

就我而言,会发生以下情况:通过sometestsite.com在我的应用程序中调用一个页面,该页面呼叫php-cgi.exe上的127.0.0.1:9000。在内部,CURL请求调用endpoint.sometestsite.com上的页面。但是,我们无法生成任何新的PHP进程来提供第二个请求。通过提供运行CURL请求的请求来阻止原始的php-cgi.exe。所以,我们遇到了僵局,一切都会超时。

我使用的解决方案(它几乎是一个黑客)是使用这个python script来生成10个PHP进程。

然后在nginx中使用上游块(根据脚本的文档)告诉nginx有10个进程可用。

然后事情完美无缺。

话虽如此,请不要在生产中使用它(你可能最好在Linux上运行nginx和php-fpm)。如果您有一个繁忙的站点,10个进程可能还不够。但是,很难知道您需要多少个进程。

但是,如果您坚持在Windows上使用php运行nginx,请考虑按照this tutorial在Cygwin中运行PHP-FPM。

答案 1 :(得分:0)

确保在用于运行cgi进程的同一用户的控制台上运行脚本。如果它们不相同 - 它们可能具有不同的权限。对我来说,问题出现在防火墙规则中,不允许为cgi进程的所有者打开外部连接。