【问题标题】:Curl does not work from PHP on Nginx and localhostCurl 不适用于 Nginx 和 localhost 上的 PHP
【发布时间】:2016-01-06 14:16:01
【问题描述】:

当我通过 SSL(通过 WPN-XM 在 Windows 上运行 nginx 1.9.4)将 Curl 请求从本地 PHP 脚本发送到本地服务器时,浏览器正在“等待”直到它收到 504 错误。 PHP-fpm 可能已经死了,因为 Web 服务器不处理任何其他请求。

当我向生产服务器发送相同的请求时,它可以正常工作。

当我从命令行发送 Curl 请求时,它就可以工作了。

当我在网络浏览器中打开最终资源时,它就可以工作了。

我花了 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);

【问题讨论】:

  • HTTP Status 504的可能重复
  • 谢谢,但我认为这不是所有 504 个问题的重复。我的脚本不需要更多时间,它是一个简单的 API 资源,仅在一次请求中调用。
  • 您是否阅读过什么是 504 错误?上游连接超时和/或服务器本身可能存在问题。您至少应该提供有关它的更多详细信息,并显示您实际用于发出请求的代码。

标签: php ssl curl nginx wpn-xm


【解决方案1】:

此脚本不适用于 WPN-XM v0.8.6 的默认配置, 因为只有一个 php-cgi 进程在后台侦听,但您的示例需要(至少)其中两个。执行 curl 请求的脚本已经使用了 php-cgi,因此 Nginx 无法将其转发给 php-cgi。这意味着您将首先遇到一个带有加载指示器的空白页面,然后遇到连接超时。

根本问题是 php-cgi 不会自动生成新进程(在需要时)。这个问题在这里讨论:https://github.com/WPN-XM/WPN-XM/issues/323

有两种解决方案:

03-2016 更新:

为了解决 WPN-XM 堆栈的情况,我默认添加了php-cgi-spawn\spawn.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%..\temp\php.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% %~dp0bin\php\php-cgi.exe -b 127.0.0.1:9100 -c %~dp0bin\php\php.ini
        %HIDECONSOLE% %~dp0bin\php\php-cgi.exe -b 127.0.0.1:9101 -c %~dp0bin\php\php.ini
        %HIDECONSOLE% %~dp0bin\php\php-cgi.exe -b 127.0.0.1:9102 -c %~dp0bin\php\php.ini
        %HIDECONSOLE% %~dp0bin\php\php-cgi.exe -b 127.0.0.1:9103 -c %~dp0bin\php\php.ini
    
  • 下一步是修改server\bin\nginx\conf\nginx.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”示例应该可以工作了。

【讨论】:

  • 非常感谢 Jens,你的包很棒,“php 上游池”方式帮助了我。但是我现在需要用 start.bat 启动服务器,我还需要做任何其他事情才能从控制面板运行这个编辑过的“start.bat”吗?
  • 很高兴你喜欢这个堆栈。不幸的是,SCP 不支持启动多个 PHP 进程。您将不得不使用批处理文件一段时间,直到下一个版本出来。 (我将扩展 SCP 配置对话框并添加一个下拉列表来选择要启动的 CGI 进程的数量。2 个进程的池将是批处理和 SCP 的新默认值,这样就没有人再遇到这个问题了。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-19
  • 2014-01-22
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多