UMGUM.COM (лучше) 

PHP + garbage collector ( Удаление устаревших файлов сессий PHP-интерпретатора. )

27 января 2013  (обновлено 31 января 2015)

OS: Linux Debian Lenny/Squeeze.
Application: Bash, PHP.

Кто имел дело с web-серверами, обслуживающими клиентов, количество которых исчисляется тысячами (хоть бы и в день, а не в минуту), знает не по наслышке о так называемых "garbage collector" - сборщиках мусора для удаления устаревших сессионных данных.

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

Обычно в PHP по умолчанию включен механизм "garbage collector", который удаляет файлы сессий, которые не использовались в течении промежутка времени заданном директивой "session.gc_maxlifetime" файла конфигурации "php.ini". "Уборщик мусора" запускается при старте механизма сессий, но не каждый раз при исполнении PHP-скрипта, а с периодичностью, определяемой соотношением величин ряда параметров конфигурационного файла "php.ini". Не буду здесь распинаться о тонкостях настройки, так как в сборке PHP для Debian всё это попросту не работает - напрочь отключено "из соображений безопасности".

В Debian старые файлы сессий PHP удаляются примитивным скриптом, периодически запускаемым планировщиком системы "cron", и только из директории "/var/lib/php5/" - так убого, что даже не сошлёшься на принцип "всё гениальное просто". Реальность такова, что каждому администратору web-сервера на Debian приходится накручивать на схему свои скрипты удаления мусора.

Задача: написать и запланировать исполнение скрипта удаляющего устаревшие объекты директорий временных файлов web-ресурсов. Определим время жизни файлов в одну неделю (на случай, если web-ресурсы хранят авторизацию только по сессии пользователя). Зачищать будем не только файлы сессий но и все остальные, которые ошибочно или намеренно не были удалены своевременно.


Первым делом инсталлируем пакет утилит поиска и обработки результатов поиска файлов:

# aptitude install findutils

Создаём скрипт, как таковой:

# touch /usr/local/etc/web/php-gcollector.sh
# chmod ug+x /usr/local/etc/web/php-gcollector.sh

#!/bin/bash

# Задаём шаблон месторасположения, в соответствии с которым будем искать сессионные и просто временные файлы
PLACE="/var/www/*/tmp"
# Задаём время, по истечению которого файлы должны быть удалены (в минутах; одна неделя)
TAGO=10080

find ${PLACE} -type f -mmin +${TAGO} -print0 | xargs --null --no-run-if-empty rm --force

exit 0

В принципе, в скрипте всё должно быть очевидным. На некоторые опции обращу особое внимание:

"-mmin n" в "find" - ищем только файлы, модифицированные более "n" минут до сего момента ("+n" в случае "больше n", или "-n" случае "меньше n");
"-print0" в "find" - указываем формировать вывод в виде строк, завершая из специальным символом "null character";
"--null" в "xargs" - указываем разбирать входящий поток на строки, не по пробелам и символам табуляции, как обычно, а по специальному символу "null character".

Явное использование "null character" при передаче аргументов между "find" и "xargs" нужно для того, чтобы исключить восприятие имени файла, включающее в себя пробельные и специальные символы, как не монолитное.

Думаю, что достаточным будет запускать "сборщик мусора" раз в пару часов:

# cat /etc/crontab

....
# Look for and purge old files and sessions of PHP
03 */3  * * *  root /usr/local/etc/web/php-gcollector.sh &
....

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


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )