Как я могу сделать тайм-аут Сценариев PHP корректно при ожидании продолжительных запросов MySQL?

У меня есть сайт PHP, который выполняет довольно много запросов базы данных. С определенными комбинациями параметров эти запросы могут закончить тем, что работали в течение долгого времени, инициировав ужасное сообщение тайм-аута. Я хочу заменить это хорошим сообщением тайм-аута, тематическим согласно остальной части моего стиля сайта.

Предупреждение обычных ответов на этот вид вопроса:

  1. "Оптимизируйте свои запросы, таким образом, они не работают так долго" - я регистрирую продолжительные запросы и оптимизирую их, но я только знаю о них после того, как пользователь был затронут.

  2. "Увеличьте свою установку тайм-аута PHP (например, set_time_limit, max_execution_time) так, чтобы продолжительный запрос мог закончиться" - Иногда, запрос может работать в течение нескольких минут. Я хочу сказать пользователю, что существует проблема перед тем (например, после 30 секунд).

  3. "Используйте register_tick_function для контроля, сколько времени сценарии работали" - Это только выполняется между строками кода в моем сценарии. В то время как сценарий ожидает ответа от базы данных, функция галочки не становится названной.

В случае, если это помогает, сайт создается с помощью Drupal (с большим удовлетворением требованиям заказчика) и работает на виртуальном выделенном сервере Linux на PHP 5.2 с MySQL 5.

10
задан Mark B 14 May 2010 в 10:37
поделиться

3 ответа

Документы по обработке соединения - это то, что вам нужно.

По сути, вам нужно зарегистрировать функцию выключения с помощью register_shutdown_function () . Эта функция будет вызываться всякий раз, когда сценарий будет завершен, независимо от того, был ли он завершен успешно, отменен пользователем (клавиша ESC) или истекло время ожидания.

Эта функция выключения может затем вызвать функцию connection_status () . Если connection_status () возвращает 2 (TIMEOUT) и предыдущая страница была той, которая запускала проблемный запрос, вы можете перенаправить пользователя на страницу с сообщением «Извините, но сейчас мы испытываем высокую нагрузку на сервер» или что-то еще.

0
ответ дан 4 December 2019 в 04:36
поделиться

Отсутствуют асинхронные вызовы mysql и возможности для разветвления облегченных потоков.

Хотя вы можете разделить свой PHP-код на два уровня и использовать соединение между ними, которое вы можете вызывать асинхронно, проблема с этим подходом заключается в том, что уровень БД все равно будет пытаться выполнить запрос после того, как верхний уровень откажется от получения результаты возвращаются - потенциально блокирующая СУБД для других пользователей. (у вас больше шансов получить более частые запросы на страницы, срок ожидания которых истекает).

У вас возникнет та же проблема, если вы передадите обработку тайм-аута на обратный прокси-сервер, расположенный перед веб-сервером.

Наиболее разумным местом для реализации тайм-аута является сама база данных, но, AFAIK, mysql этого не поддерживает.

Следующим вариантом является создание прокси-сервера между PHP и базой данных - он может быть самодостаточным - создание 2 легких потоков для каждого запроса (1 для выполнения запроса, 2-й в качестве сторожевого таймера для уничтожения первого, если он слишком важен. long) - но это требует не только написания кода в lnaguage, который поддерживает легкие потоки, но и определения протокола для связи с PHP.

Однако, используя другой подход к модели прокси - вы можете создать отдельный процесс PHP с помощью proc_open и установить для потока stdout неблокирующий режим - таким образом ваш PHP может продолжать работать и проверять, запущен ли прокси. запрос. Если он истекает, то как родительский элемент прокси-сервера он может сигнализировать ему о завершении работы (proc_terminate ()), что должно остановить выполнение запроса в базе данных.

Конечно, это будет означать много работы по развитию.

Может оказаться намного проще настроить одну или несколько подчиненных СУБД для выполнения ваших медленных запросов - возможно, с интеллектуальной балансировкой нагрузки. Или посмотрите другие способы ускорить выполнение медленных запросов - например, предварительную консолидацию.

HTH

C.

3
ответ дан 4 December 2019 в 04:36
поделиться

Ваш сервер настроен на APC, Memcache, Boost и Drupal Cache? Это альтернативные маршруты, которые работают очень хорошо.

В противном случае, какие скрипты, работающие в Drupal, могут вызвать это? Просто из любопытства используете ли вы представления и панели?

-1
ответ дан 4 December 2019 в 04:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: