Я борюсь с причудливой проблемой и заканчивая идеями, надеюсь, что кто-то здесь может мне помочь. Речь идет о случайном тайм-ауте подключения к внешнему серверу - очень часто при запуске из браузера, но очень редко при запуске из 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-адресов и т. Д.). Я хотел бы поблагодарить всех, кто пытался помочь мне в этом вопросе. Видимо, мы ничего не могли сделать.
Ваш сервер основан на Linux или Windows? Это общий хостинг или выделенный сервер с назначенной пропускной способностью? – Ghigo
Это основано на Linux, размещенном в собственном центре обработки данных моей компании. Bandwitdh очень широк и размер данных, возвращаемых внешним сайтом, составляет менее 100 символов (плюс HTTP-заголовки). – pstryk
Вы говорите о 150 запросах в секунду. Это 9000 запросов в минуту. Менее 7 минут вы используете все серверные сокеты. Вы должны настроить свою Linux-систему для такой нагрузки. Кроме того, подумайте о связях keep-alive и небольшом демоне для обработки такого трафика, вы тратите много сетевых ресурсов на эту реализацию. – Ghigo