1

Я борюсь с причудливой проблемой и заканчивая идеями, надеюсь, что кто-то здесь может мне помочь. Речь идет о случайном тайм-ауте подключения к внешнему серверу - очень часто при запуске из браузера, но очень редко при запуске из CLI. Более подробная информация и код:PHP fsockopen таймаут соединения через браузер, но не через CLI

На моем сайте example.com У меня есть форму. Как только пользователь отправляет его (HTTP POST), php отправляет запрос (другой POST) на внешний сервер http://external.com/check.php с некоторыми POST-данными. Как только он получает ответ, он переходит к выполнению остальной части кода и выводит веб-страницу в конце. Это выглядит следующим образом:

if (!empty($_POST) { 
    // here goes some POST validation stuff, and then: 
    req = http_build_query($_POST); 
    $http_request = "POST /check.php HTTP/1.0\r\n"; 
    $http_request .= "Host: external.com\r\n"; 
    $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; 
    $http_request .= "Content-Length: " . strlen($req) . "\r\n"; 
    $http_request .= "User-Agent: SpeciallyDefinedForExternal.com/PHP\r\n"; 
    $http_request .= "\r\n"; 
    $http_request .= $req; 
} 

if (false == ($fs = fsockopen($host, $port, $errno, $errstr, 10))) { 
    throw new Exception($errstr, $errno); 
} 

fwrite($fs, $http_request); 
while (!feof($fs)) { 
    $response .= fgets($fs, 1024); // One TCP-IP packet 
} 
fclose($fs); 

// do some stuff depending on on $response 

Все отлично работает, когда я запускаю его на сервере разработки, но когда я развернуть его производство, он случайно продолжает бросать исключения в fsockopen() вызова.

Я проверил в файлах журнала, что около 15% от fsockopen() звонков успешны, а остальные 110 Connection timed out ошибок.

Самое странное, что когда я вхожу на рабочий сервер и запускаю тот же фрагмент кода через CLI, тогда только 0,1% запросов сталкиваются с ошибкой таймаута соединения, а 99,9% работают безупречно! Даже если я вложу петлю 2000 итераций, соотношение останется прежним.

Я разговаривал с администраторами external.com, и они сказали, что у них всего 5% загрузки сервера, а у других их клиентов нет проблем с тайм-аутом, поэтому похоже, что это что-то с моей проблемой php или сетью.

Конфигурация моего сервера разработки и производственного сервера идентична, с той лишь разницей, что нагрузка составляет около 150 запросов в секунду. Чтобы быть ясным: эти 150 запросов являются моими посетителями, но не каждый из них представляет форму и открывает сокет. В секунду таких пользователей около 14, т. Е. Около 14 POST в секунду отправлено на external.com с моего сервера.

Когда я попытался заменить fsockopen() с curl, он стал еще лучше - в настоящее время около 45% почт, посланных в external.com были успешными (через браузер) - который по-прежнему неудовлетворительно. Когда я бегу от CLI - он работает отлично. И сообщение об ошибке несколько отличается, но на самом деле означает то же самое: couldn't connect to host.

Любые идеи, что может быть причиной того, что запросы через браузер, как правило, терпят неудачу, в то время как те, которые отправляются через CLI, работают нормально?

Если это имеет значение: я использую php 5.3.27, а мой веб-сервер - Apache. Номер версии идентичен, когда я вызываю phpinfo() через браузер и php -v через CLI.

Спасибо заранее,

Pstryk

* EDIT *

Оказалось, что проблема в их конфигурации маршрутизатора.

Администраторы external.com не видели увеличения нагрузки, потому что они смотрели на неправильную машину. Существенный виновник лица их маршрутизатор, а не сервер external.com. Они что-то изменили в конфигурации маршрутизатора, но не раскрывают, какая настройка была именно так, я думаю, мы никогда не узнаем. Смешно, что, поскольку они исправили проблему, теперь та же проблема появляется на моем сервере разработки ... но с этим я могу жить. Чтобы быть ясным: на моей стороне сервер разработки использует другой маршрутизатор, чем производственный сервер, но их конфигурация одинакова (кроме IP-адресов и т. Д.). Я хотел бы поблагодарить всех, кто пытался помочь мне в этом вопросе. Видимо, мы ничего не могли сделать.

+0

Ваш сервер основан на Linux или Windows? Это общий хостинг или выделенный сервер с назначенной пропускной способностью? – Ghigo

+0

Это основано на Linux, размещенном в собственном центре обработки данных моей компании. Bandwitdh очень широк и размер данных, возвращаемых внешним сайтом, составляет менее 100 символов (плюс HTTP-заголовки). – pstryk

+0

Вы говорите о 150 запросах в секунду. Это 9000 запросов в минуту. Менее 7 минут вы используете все серверные сокеты. Вы должны настроить свою Linux-систему для такой нагрузки. Кроме того, подумайте о связях keep-alive и небольшом демоне для обработки такого трафика, вы тратите много сетевых ресурсов на эту реализацию. – Ghigo

ответ

0

Возможно, вы уже проверили, но конфигурация действительно идентична для php-cli, mod_php (dev, stage, live)? Кажется, что настроен очень короткий тайм-аут. Это также объясняет различное поведение fsockopen и curl, у них разные настройки iirc.

Просьба посмотреть: http://php.net/stream_set_timeout в документации fsockopen замечено, что тайм-аут предназначен только для открытия сокета.

+0

Да, все эти конфигурационные файлы идентичны (за исключением вещей, которые должны быть разными). Первый пример в http://php.net/stream_set_timeout показывает, что мне нужно установить тайм-аут для уже открытого соединения, но в моем случае соединение не открывается из-за таймаута;) Другими словами - он может 't установить соединение, для которого я могу установить тайм-аут. – pstryk

 Смежные вопросы

  • Нет связанных вопросов^_^