Yvision.kz
kk
Разное
Разное
399 773 постов41 подписчиков
Всяко-разно
0
23:09, 08 сентября 2010

Асинхронность PHP, очередная попытка изменить мир

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

Итак, о чём это я? Асинхронность. Ваши скрипты, которые выдают что-то в браузер клиенту (будь то html-код, картинка или заголовок "302 Location /somewhere/else") должны делать как можно меньше операций. Всё, что делается в таких скриптах - делается синхронно (пришёл запрос, обработали данные, выдали результат). Всё, что делается синхронно - заставляет клиента ждать. Когда клиент вынужден ждать, он начинает ненавидеть ваш сайт и лично вас. Когда клиент ненавидит вас, у вас портится карма, потом здоровье и вас начинают преследовать неприятности :)

Как этого избежать? Делать как можно больше работы асинхронно. Для этого, в большинстве случаев, вполне хватает возможностей cron'а и php-скриптов.

Например, вам нужно отправить сообщение с подтверждением регистрации по электронной почте. Как делают обычно?

register_user();
mail($to, $subject, $body, $headers);
echo
"Спасибо за регистрацию";

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

Чтобы избежать тормозов нужно воспользоваться фичей, которая называется очередью сообщений. Вместо отправки сообщения напрямую на почту мы можем записать его в файл или в базу, а обработать этот файл или запись в скрипте, который будет вызван из cron'а.

Да, пользователь получит письмо через минуту, а не моментально. Но эта задержка не критична для пользователя и для работы сайта, зато сайт будет работать значительно быстрее.

Другой пример - кеширование. Можно генерировать кеш так:

if(!($entry = $cache->read($key))) {
$entry = get_entry($key);
$cache->save($entry, $key);
}

Проблема здесь в том, что некоторые пользователи будут запрашивать страницу, когда кеш пуст. Если на получение значения (функция get_entry) требуется значительное время, пользователи будут ждать. А если в этот момент на сайт зайдёт значительное количество пользователей, сайт может упасть.

Решение, конечно же - асинхронность. Мы можем генерировать кеш из cron-скрипта, например, раз в 3 минуты, выставив время жизни кешу 4 минуты. Таким образом, пользователи сайта всегда будут получать информацию из кеша.

А можно поступить иначе - воспользоваться всё той же очередью сообщений. Заводим в базе таблицу, в которую будем писать ключи кеша, которые нужно перегенерировать. Cron-скриптом обрабатываем очередь и обновляем кеш. На сайте, скажем, при публикации комментария добавляем запись с нужным ключём в очередь, чтобы через минуту этот ключ обновился. Таким образом мы не привязываем обновление кеша к определённому временному промежутку, любой ключ может быть обновлён в любое время.

Подводя итог - используйте асинхронность везде, где это только возможно. Например, на главной странице сайта www.zakon.kz синхронно выводится только блок авторизации.

Ps: Тут ещё один пример применения асинхронности и очереди сообщений для оптимизации счётчика посещений

0
539
5