apache — параллельный запрос на тот же PHP-скрипт вызывает вторую длительную задержку

Фон

Это то, что сводит меня с ума на несколько недель. Я использую скрипт PHP Minify MrClay для минимизации и объединения моих JS и CSS. Это прекрасно работает, все мои файлы объединены в common.css и common.js, которые являются виртуальными файлами, переведенными для ссылки на скрипт следующим образом:

RewriteRule ^common.js$ /tynamic/min/?g=js [L,QSA]
RewriteRule ^common.css$ /tynamic/min/?g=css [L,QSA]

Строка запроса также добавлена ​​для обозначения версии этих файлов, и они имеют кеширование продолжительностью 3 года, поэтому человеку, посетившему мой сайт, скорее всего, никогда не придется загружать какие-либо CSS или JS при любом будущем посещении этого сайта (если они не меняйся, очевидно). Пока все работает.

Эта проблема

Часто (к сожалению, не всегда), когда мой браузер запрашивает эти 2 файла (что делается одновременно), один из файлов занимает секунду, чтобы вернуться. Это всегда тот, чей запрос поступает позже на сервер, поэтому его обычно тот, который позже в HTML, но это не правило.

Смотрите эти скриншоты:

взято из моего Firefox

протокол испытаний Pingdom

Я бы согласился с тем, что сервер помещает другой файл в очередь и обрабатывает его после первого, но это не займет целую секунду.
Еще несколько вещей: никакие действия, такие как конкатенация или gzipping не выполняются в этом случае … скрипт только выполняет fpassthru () из существующего предварительно сжатого файла. Однако это происходит не всегда … там становится немного странно, если я выполняю большое количество последовательных загрузок страниц, например, 30 или более, он возвращается к «нормальному», когда оба файла обрабатываются за тривиальное время , Затем, когда я проверяю через некоторое время, он снова на втором зависании. Время всегда немного больше секунды.

Что я уже пробовал

  1. Ввод if($_GET["g"]=="js") exit; прямо в начале сценария.

Это верно, это не помогло. Файл все еще задерживался, ничего не выводя. Просто exit; (для обоих файлов) однако работает … 🙂

  1. Сроки сценариев

Оба прогона сообщают о минимальном времени (единицах или десятках миллисекунд) своих прогонов, поэтому нет функции, которая бы задерживала это.

  1. Другой сервер / хостинг

Без справки, 3 разных сервера и хостинг провайдеры. Это не связано с хостингом.

  1. Создание полной копии сценария

Поэтому я сделал копию полного каталога скриптов, чтобы оба запуска выполнялись с использованием разных файлов — без помощи.

  1. Отключение блокировки файлов и других настроек скрипта config или самого скрипта.

Пока я ничего не придумал 🙁

  1. Другой сценарий — делать что-то еще.

Это было интересно, изменяя файлы, чтобы сделать что-то еще, например, сделать скандир и выбрать файл тоже не помогло. Другой анализ показал, что PHP-скрипты присваиваются свободным потокам процессора. каждую секунду. Так что, если есть, например, 5 потоков и 6 сценариев должны быть запущены одновременно, первые 5 выполняются примерно за 10 мсек, но 6-й должен ждать целую секунду, чтобы даже начать обрабатываться … Почему это происходит?

Большое спасибо заранее за любые усилия, приложенные, чтобы помочь мне

6

Решение

CBroe, вероятно, прав. Если вы используете сессии (session_start ()), PHP будет одновременно обслуживать только один запрос к одному клиенту (session_id). Пока один запрос обслуживается, другой ставится в очередь, пока первый сеанс не записывает сеанс. Файл сеанса заблокирован для предотвращения записи нескольких запросов в один сеанс, что может привести к неожиданным результатам. Сессия записывается либо по завершении сценария, либо путем вызова session_write_close (). Это освободит вашу сессию для следующего запроса.

Однако я чувствую себя обязанным сказать вам, что вы делаете это неправильно. Вы не должны минимизировать JS и CSS с помощью PHP. Вот причины:

  1. Использование PHP для этого вызывает ненужную нагрузку на сервер
  2. Браузер все еще запрашивает файлы, чтобы получить ответ 304 — снова ненужная нагрузка на сервер и снижение пользовательского опыта (эти запросы все еще занимают время)
  3. Трудно создать хороший инструмент минимизации, и нет необходимости изобретать велосипед. Лучший из них легко доступен.
  4. Там больше причин …

Я предлагаю вам лучше потратить свое время не на написание сценариев минификации, а на изучение инструментов сборки (Grunt или Gulp), которые будут выполнять эту работу за вас и гораздо больше, чем вы захотите / сможете написать на PHP.

В двух словах, как весь этот процесс работает

  1. Вы настроили свой сервер для отправки заголовка Expires. Это не позволит клиенту даже запрашивать изменения в файлах. Google для того, как это сделать с помощью Apache: https://www.google.com/search?q=apache+expires+htaccess&то есть = UTF-8&ОЕ = UTF-8&gws_rd = кр&е = y12dVrqKG8KvsAHFiKjYDA
  2. Настройте описанные выше инструменты для «создания» ваших минимизированных ресурсов — объедините несколько файлов, «скомпилируйте» таблицы стилей, минимизируйте и т. Д. Таким образом, эти встроенные файлы хранятся на диске и обслуживаются непосредственно веб-сервером.
  3. Вы только настраиваете сайт, чтобы использовать минимизированные ресурсы в производстве. (Вы хотите иметь возможность отлаживать полный исходный код в разработке).
  4. При развертывании любых изменений на вашем сайте.

Умение настроить это очень пригодится любому веб-разработчику. Кроме того, это освободит ваше время для создания самого веб-приложения.

2

Другие решения

Вопрос не решен, однако я нашел хостинг-провайдера, с которым эта проблема просто не появляется. Тогда это проблема хостинга, и это должно быть связано с тем, как он назначает потоки PHP запросам — кажется, что мои старые хосты делали это ТОЛЬКО с помощью одной секунды. Это все, что я знаю сейчас.

0

По вопросам рекламы [email protected]