Curl не работает из PHP на Nginx и localhost

Когда я отправляю запрос Curl из локального PHP-скрипта на локальный сервер через SSL (работает nginx 1.9.4 в Windows через WPN-XM), то браузер "ждет", пока не получит ошибку 504. PHP-fpm, вероятно, мертв, потому что веб-сервер не обрабатывает любой другой запрос.

Когда я отправляю тот же запрос на производственный сервер, он работает правильно.

Когда я отправляю запрос 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);

1 ответ

Решение

Этот сценарий не будет работать с конфигурацией по умолчанию WPN-XM v0.8.6, поскольку в фоновом режиме прослушивается только один процесс php-cgi, но вашему примеру нужны (как минимум) два из них. php-cgi уже используется сценарием, выполняющим запрос curl, поэтому Nginx не может переслать его в php-cgi. Это означает, что вы сначала столкнетесь с пустой страницей с индикатором загрузки, а затем выберете время ожидания соединения.

Основная проблема заключается в том, что php-cgi не запускает автоматически новые процессы (когда это необходимо). Эта проблема обсуждается здесь: https://github.com/WPN-XM/WPN-XM/issues/323

Есть два решения:

  • использовать инструмент для порождения серверов, как
  • или запустите больше процессов php-cgi и настройте балансировку нагрузки / восходящий пул nginx

Обновление 03-2016:

Чтобы решить ситуацию со стеком WPN-XM, я добавил php-cgi-spawn\spawn.exe по умолчанию. Это позволяет создавать несколько PHP-демонов. Спавнер будет использоваться в версии PHP ниже v7.1.

В PHP v7.1 будет реализовано это решение, которое обеспечит улучшенное мультиплексирование FCGI из коробки.


мицелий-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"

Я понятия не имею, где скрывается этот инструмент, возможно, где-то есть отдельная загрузка, но, возможно, это часть дистрибутива lighttpd для Windows. Я думаю, что я скомпилирую его из исходного кода и сделаю его доступным для WPN-XM.

php upstream pool

Второе решение требует двух небольших шагов для запуска и работы пула 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" должен сработать.

Другие вопросы по тегам