我正在看到我正在构建的PHP应用程序存在一个非常奇怪的问题。
我的开发服务器上有2个虚拟主机(Windows 7 64位)sometestsite.com
和endpoint.sometestsite.com
。
在我的hosts
文件中,我将sometestsite.com
和endpoint.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.com
到endpoint.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问题。
任何人都可以提供一些见解/过去的经验,为何会发生这种情况?
答案 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进程的所有者打开外部连接。