Если посещаемость сайта высока, а время жизни сессии достаточно большое, то объём всех файлов сессий может достигать десятков гигабайт. Очевидно, что в таких условиях на удаление старых сессии придётся потратить значительное время. И пользователь сайта не увидит страницу до тех пор, пока процедура не завершится.
Этой проблемы можно избежать, если отключить проверку сессий на хитах. И проводить её только на отдельной задаче, которая будет запускаться по CRON планировщику. Так пользователи не будут участвовать в процессе удаления старых сессий совсем. Что ускорит сайт.
Отключение проверки сессий на хитах
В конфигурационном файле apache для PHP можно прописать две директивы: session.gc_probability и session.gc_divisor. Они задают вероятность запуска процесса по удалению удаления старых сессий (на каждой 100-ой загрузке страницы сайта).session.gc_divisor в сочетании с session.gc_probability определяет вероятность запуска функции сборщика мусора (gc, garbage collection) при каждой инициализации сессии. Вероятность рассчитывается как gc_probability/gc_divisor. То есть 1/100 означает, что функция gc запускается в одном случае из ста, или 1% при каждом запросе. session.gc_divisor по умолчанию имеет значение 100.
Для остановки стандартной функции удаления старых сессий достаточно задать session.gc_probability = 0. Делается это в файле .htaccess, в корневой директории сайта:
php_value session.gc_probability 0
Если добавить эту директиву и оставить всё как есть, то файлы сессий будут копиться до тех пор, пока весь диск хостинге не закончится. Поэтому нужно сделать свой механизм удаления сессий.
Удаление старых сессий по CRON заданию
Напишем CRON задание в файле/etc/crontab
, в котором будет происходить весь процесс удаления просроченных файлов сессий. Приведём это задание сразу, а потом рассмотрим его составляющие (далее одна длинная-длинная строка задания):0 * * * * mousedc /usr/bin/php -d session.save_path=/tmp/php_sessions/mousedc.ru -d session.gc_probability=1 -d session.gc_divisor=1 -d session.gc_maxlifetime=7776000 -r "session_start(); session_destroy();" &>/dev/null
Разберём всё по порядку:
- 0 * * * * - означает, что команда запускается раз в час
- mousedc - имя пользователя, запускающего команду. Должно совпадать с тем, от которого которого выполняются скрипты сайтов. Иначе доступа к сессионной папке у пользователя не будет, а без прав доступа скрипт не сработает.
- /usr/bin/php - обработчик php
- -d session.save_path=/tmp/php_sessions/mousedc.ru - директива, которая указывает на папку, где хранятся сессии сайта. Можно посмотреть её в phpinfo() в значении "session.save_path"
- "-d session.gc_probability=1" и "-d session.gc_divisor=1" - оба значения ставим одинаковыми, чтобы получить 100% вероятность срабатывания. Тогда при каждом запуске будет инициирован процесс удаления старых сессий
- -d session.gc_maxlifetime=7776000 - директива, определяющая максимальную продолжительность жизни сессии. Время жизни сессии - это количество секунд, прошедшее с последнего изменения сессионного файла. 7776000 секунд - это 90 дней. По умолчанию gc_maxlifetime = 1440. Задайте то значение, которое не меньше, чем используемое на сайте. Иначе сессии будут удаляться раньше, чем нужно.
- -r "session_start(); session_destroy();" - для инициации процесса очистки достаточно вызвать функцию создания сессии. А уничтожаем, чтобы и её файла не существовало.
- &>/dev/null - стирает оба потока вывода, чтобы ничего лишнего не записывалось в CRON журнал.