PHP CURL超时,但CLI CURL起作用 [英] PHP CURL timing out but CLI CURL works

查看:207
本文介绍了PHP CURL超时,但CLI CURL起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am seeing a very bizarre problem with a PHP application I am building.

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

I have 2 virtual hosts on my development server (windows 7 64-bit) sometestsite.com and endpoint.sometestsite.com.

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

In my hosts file, I configured sometestsite.com and endpoint.sometestsite.com to point to 127.0.0.1.

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

Everything works when the server was running Apache 2.4.2 with PHP 5.4.9 as a fcgi module.

然后我删除了Apache,并安装了nginx-1.2.5(Windows构建).我已将php-cgi.exe作为服务运行,并且一切正常.

I then removed Apache and installed nginx-1.2.5 (windows build). I got php-cgi.exe running as a service and everything seems to work fine.

问题在于,以前从sometestsite.comendpoint.sometestsite.com的CURL调用会超时.

The problem is that a CURL call from sometestsite.com to endpoint.sometestsite.com that previously worked would time out.

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

I then moved that piece of code by itself to a small PHP file for testing:

$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日志中收到的:

This is what I receive in the PHP logs:

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)运行相同的请求,则效果很好:

However, if I run the same request using CLI CURL (via Git Bash), it works fine:

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

这很奇怪,因为PHP的版本和使用Apache时的版本完全相同.

This is quite strange as the PHP is exactly the same version and has the same configuration as when Apache was used.

我不确定这是Web服务器配置问题还是PHP的CURL问题.

I am not sure if this is a web server configuration issue or a problem with PHP's CURL yet.

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

Can anyone provide some insight/past experiences as to why this is happening?

推荐答案

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

Nginx does not spawn your php-cgi.exe processes for you. If you came from Apache like me and used mod_fcgid, you will find that you have many php-cgi.exe processes in the system.

由于Nginx不会为您生成PHP流程,因此您需要自己启动该流程.就我而言,php-cgi.exe -b 127.0.0.1:9000是作为服务自动运行的.然后Nginx将所有对PHP的请求推送到PHP处理程序,并收到响应.

Because Nginx does not spawn the PHP process for you, you will need to start the process yourself. In my case, I have php-cgi.exe -b 127.0.0.1:9000 running as a service automatically. Nginx then pushes all requests for PHP to the PHP handler and receives a response.

问题: PHP-FPM无法在Windows上运行(自5.4.9起) . FPM是一个精巧的小流程管理器,它位于后台,并在处理请求时管理PHP进程的产生和终止.

Problem: PHP-FPM does not work on windows (as of 5.4.9). FPM is a neat little process manager that sits in the background and manages the spawning and killing of PHP processes when processing requests.

由于这是不可能的,因此在Windows上,我们一次只能处理1个请求,类似于

Because this is not possible, on Windows, we can only serve 1 request at a time, similar to the problem experienced here.

对于我来说,会发生以下情况:在sometestsite.com上的应用程序中调用一个页面,该页面调用127.0.0.1:9000上的php-cgi.exe.在内部,一个CURL请求调用endpoint.sometestsite.com上的页面.但是,我们无法产生任何新的PHP进程来满足第二个请求.通过为运行CURL请求的请求提供服务,可阻止原始php-cgi.exe.因此,我们陷入了僵局,然后一切都超时了.

In my case, the following happens: Call a page in my application on sometestsite.com which makes a call to php-cgi.exe on 127.0.0.1:9000. Inside, a CURL request calls a page on endpoint.sometestsite.com. However, we are unable to spawn any new PHP processes to serve this second request. The original php-cgi.exe is blocked by serving the request that is running the CURL request. So, we have a deadlock and everything then times out.

我使用的解决方案(几乎是一种技巧)是使用此 python脚本以生成10个PHP进程.

The solution I used (it is pretty much a hack) is to use this python script to spawn 10 PHP processes.

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

You then use an upstream block in nginx (as per the docs for the script) to tell nginx that there are 10 processes available.

然后一切正常.

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

Having said that, please do not ever use this in production (you are probably better off running nginx and php-fpm on Linux anyway). If you have a busy site, 10 processes may not be enough. However, it can be hard to know how many processes you need.

但是,如果您确实坚持在Windows上使用php运行nginx,请考虑按照

However, if you do insist on running nginx with php on windows, consider running PHP-FPM within Cygwin as per this tutorial.

这篇关于PHP CURL超时,但CLI CURL起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆