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

PHP: первое знакомство с garbage collection

Время на прочтение3 мин
Количество просмотров2.7K
Столкнулся я недавно с небольшой проблемой: данные из сессии рандомно пропадали при простое сессии больше 24 (как выяснилось позже) минут.

Вот, что рассказал мне мануал:
Просроченные сессии на самом деле не подвергаются уничтожению сразу же по истечении 24 минут. Вот как все происходит: в начале каждого запроса, использующего сессию (вследствие предварительного вызова функции session_start( ) или установки session/auto_start в on), существует 1% возможности того, что PHP-интерпретатор отсканирует все сессии на сервере и удалит любую из просроченных. «1% возможности» в отношении компьютерной программы звучит совершенно непредсказуемо. Так оно и есть. Но подобная непредсказуемость повышает общую производительность. Интенсивно работающий сайт, занятый в начале исполнения каждого запроса поиском просроченных сессий в целях их удаления, станет расходовать слишком много ресурсов сервера.

Это объясняет «рандомность» удаляемых данных.
Но как решить эту проблему, поскольку в моем проекте время простоя запросто может быть больше 24 минут.

Опять обращаемся к мануалу:
Конфигурационная директива session.gc_maxlifetime управляет установкой максимального времени бездействия между запросами, в течение которого поддерживается активность сессии. Ее значение по умолчанию составляет 1440 — именно столько секунд в 24 минутах. Изменить значение session.gc_maxlifetime возможно либо установкой конфигурации сервера, либо с помощью вызова функции ini_set( ) прямо из программы. Вызов этой функции должен состояться раньше, чем вызов функции session_start( ).

Ок, с этим теперь все понятно, но хочется все-таки по-больше узнать про этот несчастный 1% вероятности. Можно ли как-нибудь изменить это значение, если проект требует другой логики относительно данных сессии?
Не стоит полагаться на 1% вероятности при желании удалить просроченную сессию наверняка. Конфигурационная директива session.gc_probability устанавливает процент вероятности запуска подпрограммы «удалить устаревшие сессии» в начале обработки запроса. Для запуска этого процесса в начале обработки каждого запроса, значение директивы устанавливается в 100. Также, как и в случае с session.gc_maxlifetime, вызов функции ini_set( ) для изменения значения session.gc_probability должен состояться раньше, чем вызов функции session_start( ).

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

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

Надеюсь, эта информация окажется полезной для кого-нибудь…

Ссылка на упоминавшийся выше «мануал»: physics.grsu.by/seti/doc/PHP/PHP5/g8_4.html

UPDATE

От себя хочется еще добавить про нерассмотренную в данном «мануале» директиву session.gc_divisor. По-умолчанию она равна 100, и получается, что значение session.gc_probability действительно совпадает с % вероятности. На самом же деле, вероятность вычисляется как: gc_probability/gc_divisor. Т.е. при значениях:
gc_probability = 1
gc_divisor = 1000
Вероятность уже будет не 1%, а 0,1%.

Нужно отметить, что большинство хостинг-провайдеров в России (дабы снизить нагрузку на свои серверы) ставят именно такое соотношение: 1/1000, что дает очень маленькую вероятность, что по истечении 24 минут (по-умолчанию) данные все-таки будут удалены. Возьмите на заметку, если вам нужно будет настроить ваше приложение на более жесткую работу с данными сессий.
Теги:
Хабы:
Всего голосов 4: ↑3 и ↓1+2
Комментарии6

Публикации

Истории

Ближайшие события