当我通过SSL从本地PHP脚本发送Curl请求到本地服务器(通过WPN-XM在Windows上运行nginx 1.9.4)时,浏览器正在"等待",直到它得到504错误。PHP-fpm可能已经死了,因为web服务器没有处理任何其他请求。
当我向生产服务器发送相同的请求时,它会正常工作。
当我从命令行发送Curl请求时,它就工作了。
当我在web浏览器中打开最终资源时,它就工作了。
我花了4个小时在谷歌上搜索和阅读Stac Owerflow,但没有发现任何像我这样的情况。
谢谢!
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://webserver.local/resource");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // just on local
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // just on local
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
$response = curl_exec($ch);
这个脚本不能在WPN-XM v0.8.6的默认配置下工作,因为只有一个php-cgi进程在后台监听,但是您的示例需要(至少)两个。php-cgi已经被做curl请求的脚本使用,因此Nginx无法将其转发给php-cgi。这意味着你将首先进入一个带有加载指示符的空白页面,然后达到连接超时。
潜在的问题是php-cgi不能自动生成新进程(当需要时)。这个问题在这里讨论:https://github.com/WPN-XM/WPN-XM/issues/323
有两个解决方案:
- 使用一个工具来生成服务器,比如
- https://github.com/WPN-XM/php-cgi-spawner/releases
- 或
spawn-fcgi
从http://www.lighttpd.net/项目启动php-cgi
- 或启动更多php-cgi进程并配置nginx负载均衡/上游池
Update 03-2016:
为了解决WPN-XM堆栈的情况,我默认添加了
php-cgi-spawnspawn.exe
。这允许生成多个PHP守护进程。生成器将用于v7.1以下的PHP版本。PHP v7.1将实现此解决方案并提供更好的FCGI多路复用开箱即用的。
spawn-fcgi
第一个解决方案是修改start.bat
。您只需将spawn-fcgi放在php-cgi前面,如下所示:
spawn-fcgi -f "%_dir%php-cgi.exe" -a 127.0.0.1 -p 9100 -C 6 -F 4 -P "%_dir%..tempphp.pid"
我不知道这个工具隐藏在哪里,也许在某个地方有一个独立的下载,但它可能是windows lighttpd发行版的一部分。我想我会从源代码编译它,并使其可用于WPN-XM。
php上游池
第二个解决方案需要两个小步骤来启动并运行PHP工作线程池。
-
第一步是修改
start.bat
文件以启动多个php-cgi守护进程,每个守护进程监听不同的端口。我们添加了更多的php-cgi启动::start-php echo Starting PHP FastCGI... set PHP_FCGI_MAX_REQUESTS=0 set PHP_FCGI_CHILDREN=4 %HIDECONSOLE% %~dp0binphpphp-cgi.exe -b 127.0.0.1:9100 -c %~dp0binphpphp.ini %HIDECONSOLE% %~dp0binphpphp-cgi.exe -b 127.0.0.1:9101 -c %~dp0binphpphp.ini %HIDECONSOLE% %~dp0binphpphp-cgi.exe -b 127.0.0.1:9102 -c %~dp0binphpphp.ini %HIDECONSOLE% %~dp0binphpphp-cgi.exe -b 127.0.0.1:9103 -c %~dp0binphpphp.ini
-
下一步是修改
serverbinnginxconfnginx.conf
并激活php_pool
,而不是使用单个上游。只需查找
fastcgi_pass php;
并将其更改为fastcgi_pass php_pool;
。
此更改将激活以下已定义的上游池:
upstream php_pool {
server 127.0.0.1:9100 weight=1 max_fails=3 fail_timeout=20s;
server 127.0.0.1:9101 weight=1 max_fails=3 fail_timeout=20s;
server 127.0.0.1:9102 weight=1 max_fails=3 fail_timeout=20s;
server 127.0.0.1:9103 weight=1 max_fails=3 fail_timeout=20s;
}
。
运行start.bat
,然后你的"curl post to localhost"的例子应该可以工作了