На нашем сервере разработки я нажал /bigreport.php
, который подключается к MySQL и запускает отчет. Это займет несколько минут.
На другой вкладке браузера я перехожу к /smallreport.php
, который подключается к MySQL и запускает меньший отчет (но это все равно занимает минуту). Второй запрос к smallreport.php
даже не начинается, пока bigreport.php
отделка. Это тот же dev-сервер.
2-е окно: вращается счетчик браузера, на странице ничего не появляется. В MySQL SHOW PROCESSLIST
показывает только первый (из bigreport.php
). Казалось бы, PHP даже не работает для 2-го запроса.
Пока выполняется 1-й запрос (bigreport.php
), Я могу загрузить test.html
и загружается мгновенно. НО, если вместо этого я открою образец страницы PHP, phpinfo.php
, соединение зависает и даже не запустится, пока bigreport.php
закончен. В этом нет подключения к базе данных phpinfo.php
страница. Чтобы быть уверенным, я написал простую тестовую страницу PHP, которая просто: sleep(10);
с такими же результатами.
Я проверил MySQL SHOW VARIABLES LIKE 'max%connections'
и это все по умолчанию / нормально. Ограничений на количество подключений для каждого пользователя нет, по умолчанию для всех подключений - 151. Похоже, это не проблема MySQL.
Я искал ограничивающие соединения PHP, но, похоже, у него даже нет механизма для этого. PHP запускается веб-сервером, будь то Apache, IIS или что-то еще.
Так что, похоже, это проблема (или конфигурация) в IIS 7.5. Я пробовал искать «несколько подключений IIS7 на браузер / пользователя», но все, что я нашел, это помощь в настройке IIS для более чем одного веб-сайта (или виртуального хоста) на каждый IP-адрес.
Я могу ударить bigreport.php
из моего браузера, затем с другого компьютера подтянуть smallreport.php
и он работает одновременно. Это немного медленнее, но сервер не нагружен. Я могу наблюдать за активностью процессора и использованием памяти из диспетчера задач и ничего не вижу, пока работают оба этих отчета. Но если я попытаюсь загрузить оба bigreport.php
и smallreport.php
одновременно из одного и того же браузера будет работать только один. Как только тот закончится полностью, начнется следующий. Порядок не имеет значения.
Я могу загрузить несколько .html
страниц одновременно, пока bigreport.php
это работает. Эти стандартные .html
страницы загружаются практически мгновенно. Может быть, проблема в настройке FastCGI?
Я могу загрузить bigreport.php
из Firefox, затем нажмите smallreport.php
из Chrome, и он запускается одновременно! Тот же IP, та же машина (моя). Но не с другой вкладки в Firefox.
В appPool пробовал менять Максимальное количество рабочих процессов по умолчанию 1 к 2 без эффекта.
Windows Server 2008 R2 Standard, IIS 7.5.7600.16385.
Любая помощь будет оценена.
ОБНОВЛЕНИЕ 2019-05-03:
Я написал PHP-скрипт для цикла через десять секунд, повторяя число раз в секунду (с flush()
) так что я могу видеть это в счет. Я загружаю эту страницу в окно Firefox №1, затем окно №2: окно №2 ожидает завершения №1 перед запуском.
Я открываю два окна в Chrome для одной и той же страницы подсчета: окно №1 работает нормально, окно №2 ожидает завершения №1.
Затем я перезагружаю их все: открывается окно Firefox №1, но Firefox №2 зависает в ожидании Firefox №1. Окно Chrome №1 запускается, но Chrome №2 ожидает завершения работы Chrome №1.
Кажется, это ограничение на количество подключений (1) НА БРАУЗЕРА.
Это не имеет ничего общего ни со способом настройки IIS, ни с FastCGI. Это была проблема с файловой системой Windows и информацией о сеансе PHP, хранящейся в файлах. В одном браузере файл сеанса PHP открывается и БЛОКИРУЕТСЯ до тех пор, пока этот запрос не будет выполнен. Второй запрос (из того же браузера) просто ожидал снятия блокировки файла информации о сеансе. Но другой браузер был другим сеансом.
Если бы сеансы не были настроены на автоматический запуск, я, возможно, не заметил бы этого на простой странице PHP, такой как сценарий счетчика, который я написал. Но я бы заметил, что он работает bigreport.php
а потом smallreport.php
сразу после этого, поскольку они зависят от сеансов для входа в систему.
Решение простое: позвоните session_write_close()
непосредственно перед запуском запроса отчета. В моем случае после этого не требовалось никакой информации о сеансе. Если бы это было так, я мог бы сохранить эту информацию о сеансе в настраиваемый массив, например: $mysession = $_SESSION;
прямо перед session_write_close();
а затем сослался $mysession
потом.