Как стать автором
Обновить

Комментарии 34

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
поясните, пожалста, что вы имеете ввиду?
в PHP параметр mysqli.reconnect по умолчанию отключен, а следовательно при потере соединения с MySQL оно не будет «прозрачно» восстановлено
по поводу блокировки тоже не понятно
Таймаут соединения можно решить например через постоянные подключения.
Покажите где такое есть в PDO?
<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
    PDO::ATTR_PERSISTENT => true
));
?>


php.net/manual/en/pdo.connections.php
Читайте внимательно
Постоянные соединения не закрываются при завершении работы скрипта, они кэшируются и используются повторно, когда другой скрипт запрашивает соединение с теми же учетными данными

К сожалению этот параметр не решает проблему сброса соединения со стороны MySQL сервера.
Мое дело малое, показать как сделать в PDO персистентное соединение. А по поводу проблемы с таймаутами — не вижу проблемы как таковой. По умолчанию у mysql этот таймаут равен 8-ми часам если память не изменяет. С другой стороны я не вижу смысла какому-либо скрипту держать соединение с базой дольше чем минуту. Если у вас возникают проблемы с таймаутами — то скорее всего у вас просто что-то не так с реализацией задачи. Если нужно что-то долго обсчитывать в базе — открываем соединение — достаем данные — закрываем. Оно нам не понадобится пока не обсчитаем все. Можно сделать очередь задачи и все такое прочее.
Я вам А, вы мне В. Разговор был про таймаут, вы мне рассказывается про персистентное соединение, при чем тут это? Даже если все фоне то кого волнует что соединение будет персистентное? От того что оно закешируется для фоновой задачи вы где-то выиграете?
Персистентные соединения вообще ничего связанного с таймаутами, отличное от обычных, неперсистентных соединений, не имеет.

Персистентные соединения это лишь пул, который, в случае с кроновскими и шелл-скриптами вообще некому будет создать и поддерживать.
Я вел речь о запланированно долгих скриптах, а не о плохооптимизированных
Долгие операции нужно выносить за пределы, и выполнять их, например, в кроне.
вообще-то, в конце я написал о том, что долгие операции следует выполнять в фоновом режиме (в кроне это делать или запускать в качестве фонового процесса — зависит от задачи и особого значения не имеет)
3 Видео Урока Евгения Попова… используя готовые скрипты на PHP с сайта woweb.ru :)
В mysql может быть полезно установить таймауты больше, если предполагается что обработка займет продолжительное время.
SET SESSION wait_timeout (ну и interactive_timeout тоже) = 9999
да, но не всегда есть возможность менять параметры MySQL
To indicate explicitly that a variable is a session variable, precede its name by SESSION, @@session., or @@. Setting a session variable requires no special privilege, but a client can change only its own session variables, not those of any other client.

dev.mysql.com/doc/refman/5.0/en/using-system-variables.html
был неправ, спасибо за информацию
согласен, в первую очередь стоит попробовать увеличить таймаут соединения
внес поправку в статью
НЛО прилетело и опубликовало эту надпись здесь
добавил
Тогда уж добавляйте, интересный для меня, пример к
При необходимости можно периодически проверять состояние обработки при помощи AJAX запросов.


И опишите «нюанс» с mysql_reconnect (этим я уже не пользуюсь, как и mysqli_*) когда он переподключается с параметрами «по умолчанию», а не с теми параметрами, с которыми он подключался.
Не хватает примера запуска скрипта через php-cli из кода.
для nginx send_timeout и fastcgi_read_timeout (если PHP работает через FastCGI)
Потрудитесь объяснить причем тут вообще send_timeout.

Если скрипт запускается в ответ на HTTP-запрос, то пользователь может остановить выполнение запроса в своем браузере, в этом случае прекратит свою работу и PHP скрипт.
Это, мягко говоря, не всегда так.
А не лучше сделать выполнения клиентской части на клиентской машине? В наше время уже давно используется Ajax…
К чему был ваш комментарий?
Потрудитесь объяснить причем тут вообще send_timeout.

Таймаут устанавливается не на всю передачу ответа, а только между двумя операциями записями. Если по истечении этого времени клиент ничего не примет, соединение будет закрыто.

На сколько я понимаю, если скрипт отправит что-то клиенту, после чего долгое время (больше чем указано в send_timeout) будет «молчать», то соединение закроется. Поправьте если я ошибаюсь

Это, мягко говоря, не всегда так.

Ну как я и написал за это в PHP отвечает параметр ignore_user_abort. Если вам есть что добавить, то я готов это добавить в статью.
На сколько я понимаю, если скрипт отправит что-то клиенту, после чего долгое время (больше чем указано в send_timeout) будет «молчать», то соединение закроется. Поправьте если я ошибаюсь
Скрипт ничего клиенту не отправляет, этим в данном случае nginx занимается.

Фразу «клиент ничего не примет» следует понимать буквально: клиент не принял отправленных ему данных в течение заданного времени, nginx сделал write() в сокетный буфер, но последний так и остался в том же состоянии, нового события на запись не наступило. Ну а если все записанные данные в сокет успешно отправляются, то таймер выключается.

Ну как я и написал за это в PHP отвечает параметр ignore_user_abort. Если вам есть что добавить, то я готов это добавить в статью.
Я в том сообщении процитировал конкретное ваше заявление. Вы полагаете, что у сервера всегда есть возможность узнать о том, что клиент нажал кнопку stop в браузере и закрыл соединение (если вообще закрыл). Нет, часто это невозможно сделать, пока не начнешь писать в сокет, а писать нечего, пока ваш скрипт не вернул ответ. Более того, если вы ещё и кэш включите, то даже в случае когда закрытие соединения было четко детектировано, с точки зрения php ничего не произойдет, поскольку нам нужно заполнить ячейку кэша. Даже если кэш не используются, то могут быть включены опции: fastcgi_ignore_client_abort и proxy_ignore_client_abort. PHP не общается с клиентом напрямую, а полагается только на то, как поведет себя сервер приложений, который взаимодействует с веб-сервером, но даже у последнего не всегда есть достаточно информации о том, что проихошло на той стороне.

— Что же касается статьи в целом, то это отличный пример того, как не надо делать обработку долгих задач. Проблеск этого понимания промелькнул только в конце статьи, да и то был испорчен витиеватым и неубедительным объяснением, почему обработку следует производить в фоне. На первый абзац из «Нагрузка на веб-сервер», можно только ответить: для этого люди и используют nginx!

Обработку следует производить не просто в фоне, а последовательно, с использованием очереди заданий и менеджера, который эту очередь разгребает. Потому, что ваш сервер в принципе может быть не в состоянии обрабатывать параллельно то количество задач, которое на него поступило в данный момент. В целом он вряд ли способен обрабатывать их эффективно, если количество CPU-bound потоков привышает число имеющихся в распоряжении вычислительных ядер.

Ну и да, в статье полностью перемешаны в винегрет CPU-bound и I/O-bound, т.е. задачи, требующие разных подходов для их решения. Да и решать такие задачи на php можно наверное только если ничего больше не знать, что уже само по себе должно быть моветон.
Два чая, этому господину…

Всё ждал, кто же наконец предложит использовать очереди?
Спасибо за критику, статья и вправду получилась немного сумбурной (мало опыта в написании статей). Но все же я не ставил своей целью описывать разные типы долгих задач и методы их решения. Я лишь хотел написать о факторах, которые могут помешать работе таких скриптов.

По поводу того, что не надо решать такие задачи на PHP, не соглашусь. Если у вас уже есть веб-приложение, написанное на PHP, со своими классами и библиотеками, и в нем вам нужно добавить, например, функцию импорта, в которой будут использоваться эти классы и библиотеки, то я не вижу смысла реализовывать ее на другом языке.
На чем реализовывать вопрос десятый. Дело в том как реализовывать. Долгие скрипты реализовывать как веб-страницы не тру.
if (lockStart('script.php'))
{
    // основной код скрипта
    ...
    lockStop('script.php');
}

Старайтесь избегать подобных подходов. Любая ошибка или непредусмотренная ситуация в скрипте и вы попали, как говорится. Вообще ПХП мало предназначен для подобного и лучше как можно больше вещей доверять профессионалам — ОС.
lockStart($key, $params, $lock_set_timeout, $expire_sec);
lockStop($key, $params, $timeout);
prolong($key, $params, $time_sec);
Ну и какой-нибудь kill($key,...)
с mysql все не однозначно, если вы налетели на mysql has gone away в транзакции то реконектиться нельзя, т.к часть данных уже уже потеряли. те влоб использовать подход с реконектом незя

У php-fpm есть замечательная штука fastcgi_finish_request()

А вообще, если у Вас очень долгий скрипт после HTTP запроса от пользователя, то это потенциальная угроза DoS атаки.
Если скрипт запускается в ответ на HTTP-запрос, то пользователь может остановить выполнение запроса в своем браузере, в этом случае прекратит свою работу и PHP скрипт.

Это не совсем так. Не помню, как оно у апача, но в связке nginx + php-fpm от nginx команда уходит на php-fpm, и продолжает выполняться вне зависимости от того, стопнул юзер запрос или нет.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории