Arm1.ru

Заметка про сессии в PHP и Garbage Collector

Неприятную штуку тут на одном из рабочих серваков обнаружил. 

Исторически сложилось, что при старте PHP-движка сайта выставляется значение:

session_save_path( PATH_TMP );

ini_set( 'session.gc_maxlifetime', 1800 );

То бишь у нас кастомная директория для хранения сессий, и время жизни ей выставлено в полчаса для garbage collector. 

На сервере используется php-fpm. Обнаружил проблемы в логах - будто бы место закончилось на диске. Хотя его ещё дофига. Сразу мысль - где-то дофига файлов мелких насоздавалось. Как оказалось - не стирались файлы сессий в нашей кастомной директории. Стал копаться - на php.net нахожу параметр session.gc_probability, который в php.ini должен быть выставлен в 1 - это вероятность того, что при выполнении скрипта запустится ещё и garbage collector.

В подсказках пользователя запись, что Debian выставляет этот параметр в 0. Гугление говорит, что это связано с выставленными на дефолтную папку /var/lib/php5 правами, которые не позволяют php-шному garbage collection очищать старые файлы оттуда. То есть он отрубает garbage collector у php и вроде как от рута запускает какое-то своё cron-задание для очистки. Ищет он файлы, похоже, в стандартной директории, а т.к. оно не совпадает с нашей директорией PATH_TMP - то сессии не удалялись. 

Вот такие пироги. Выход - либо настроить своё cron-задание для очистки, например:

0,30 * * * * find /path/to/tmp -mmin +30 -exec rm {} \;

Либо в php.ini прописывать дефолтную папку. Но, например, если на сайте 2 проекта, которые используют разные временные папки для хранения сессий, то тут уже придётся для обоих как-то что-то настраивать.

Либо при старте скрипта добавить строчку: ini_set('session.gc_probability', 1);

Лично мне больше нравится своё cron-задание. Хотя может и добавление ещё одной строчки в скрипт - лучше, т.к. на будущее может избавить от этой проблемы. Хотя cron как-то кажется надёжнее. Осталось придумать теперь, как мне удалить накопившиеся за 6 месяцев файлы. Midnight Commander часа 2 у меня сканировал папку. Когда счётчик перевалил за 49 миллионов - я забил на сканирование, поставил удаление и пошёл спать. 

Такие дела.

keyboard_return back