PHP, ISA web proxy, тормоза file_get_contents и прокси сервер–решаем проблему с задержками file_get_contents(URL) и curl_exec
Так обычно и бывает – стоит только реализовать какой-либо сервис на сайте, тут же и конкуренты сделают тоже самое, и, как правило – ещё и лучше. Так получилось и у меня. Прицепил поисковый сервис на сайт турагентства своей жены. И этот сервис для целей авторизации на серверах провайдера этого сервиса использует прокси – скрипты, использующие file_get_contents
на стороне нашего сервера для загрузки поисковых форм и результатов поиска с серверов провайдера. После реализации я не обратил внимания на существенные задержки (до 5 секунд), у конкурентов такого сервиса вообще не было. Но вот – появился. И без задержек. Что же, разберёмся с причинами задержек в моём случае и устраним их.
Времени на поиски убил много. Приведу кусок кода для тестирования:
error_reporting(0); ini_set('default_socket_timeout', 29); $url = $base_url.$type."?".$_SERVER['QUERY_STRING']; $context = stream_context_create( array( 'http' => array( 'method' => "GET", 'header' => array ( "Accept-language: ru", "Connection: close", "Content-Type: text/html; charset=utf-8" ) ) ) ); $page = file_get_contents($url, false, $context); if(!($page === false) && strlen($page) > 0) { echo $page; } else { echo "В настоящее время сервис недоступен"; }
Можно обойтись и без создания контекста, результат будет тот же – на file_get_contents
возникает задержка (порядка 5 секунд). Свои приключения описывать не буду, опишу лишь результат.
Причина оказалось банальной. Мой web сервер построен на базе Windows 2008 R2 Web Server, IIS7 + PHP 5.3. Сервер находится в локальной сети за ISA Server. Установлен FWC. И для internet explorer указан прокси сервер (на ISA хосте).
Выяснилось следующее: PHP на IIS7 при внешних запросах использует параметры подключения IE, то есть в моём случае – подключение через прокси сервер. Стоило мне отключить прокси для web сервера с PHP, предварительно дорисовав необходимые разрешающие правила на ISA – и задержки исчезли!
Есть варианты “отключения” прокси непосредственно в php сценарии, но это решение мне не кажется целесообразным. Так что – отключайте прокси в IE для сервера IIS7+PHP.
Отзывы » (8)
RSS комментарии
Обратная ссылка
Как выяснил сейчас, проблема не только в
file_get_contents
. Проблема ещё и в резком падении производительностиecho
при большом объёме (больше 10 Кб) информации.Пришлось лечить следующим костылём (время выдачи страницы сократилось с 10 секунд до долей секунды):
Сейчас разбираюсь с причинами этого поведения, найду — опишу.
Как выяснилось, было достаточно поправить php.ini:
и можно вышеприведённый костыль не использовать. Однако, столько геморроя из-за таких вот мелких недоработок…
P.S. Подобная проблема описана здесь.
Сегодня выяснил ещё один факт прелестный. Делаю запрос к прокси скрипту, который через
file_get_contents
получает и отдаёт черезecho
порядка 15 Кб через прокси сервер — 10-15 секунд задержка. Отключаю прокси сервер — в районе 1 секунды. Будем искать дальше…Причём — чёткой системы нет. Через некоторое время через тот же прокси, с того же клиента — и задержки нет. Использую HTTP 1.1 через прокси сервер.
Короче — системы и причины задержки на
echo
пока чёткой не нашёл.Черезecho microtime()опять заметил задержку в
file_get_contents
в 9 секунд. В результате заменил на следующий код:Результат — 0.2 секунды. Хотя причину так и не нашёл.
Нашёл таки закономерность. Только пока не могу её объяснить. В общем — система следующая.
- имеем задержку, причём как на
file_get_contents
, так и наcurl_exec
, задержка в 9-10 секунд.- на том самом сервере, на котором крутится наш IIS7 + PHP, запускаем IE и открываем интересующий нас url (ну — тот самый, который мы пытаемся получить через
file_get_contents
)- и после этого задержка при выполнении php скрипта пропадает!
При этом кеширование невиновно (ответ не кешируется, имеет динамически генерируемые данные). Так что же всё-таки может быть причиной такого поведения?
Проблема по-прежнему была, как я понял, в прокси. Пришлось всё-таки в сценарии его явно прописать:
И задержки пропали.
Вывод могу сделать пока только один. Сборка PHP под Windows использует настройки IE для определения необходимости использования прокси сервера. И если таковой прописан — идёт к нему. И проходит авторизацию при необходимости. А у меня через политику «спускается» флаг «автоматическое определение прокси-сервера». Как следствие — PAC и прочие прелести. Стоило явно задать прокси и авторизацию — задержки пропали.
Осталось последнее «но»: эти параметры необходимо вынести в настройки сайта, на худой конец — в php.ini. Будем искать…
И пока всё, что нашёл для установки параметров «по умолчанию»:
stream-context-set-default
.Вот спасибо добрый человек!Все четко и ясно. Столкнулся с той же проблемой практически