Разъяснение PHP сборки мусора - PullRequest
37 голосов
/ 20 октября 2011

Из руководства по PHP, session.gc_probability и session.gc_divisor утверждают, что gc будет происходить на основе этой вероятности. Я понял.

Что мне неясно, так это то, является ли эта вероятность сеансом по сеансам или в целом.

Так что, если моя вероятность составляет 1% (1/100), что GC произойдет, означает ли это, что если один сеанс продолжает расширяться, каждый раз, когда происходит изменение на 1%, этот конкретный сеанс будет очищен? Или это означает, что 1% всех существующих сеансов (а также новых) будет запускать GC для всех других существующих сеансов?

Я уверен, что это последнее, я просто хочу убедиться.

Цель этого вопроса заключается в том, чтобы на нашем сайте я хотел, чтобы пользователи проводили долгосрочные сеансы (6 месяцев). Если 1% всех сеансов запускает GC, то это эффективно устраняет необходимость проведения такого долгосрочного сеанса, поскольку GC будет происходить каждый час или два.

Ответы [ 3 ]

11 голосов
/ 20 октября 2011

Каждый раз, когда скрипт PHP выполняется и запускает сеанс, существует вероятность, что он пройдет по папке сеанса, завершив старый сеанс.

Очистка удалит только те сеансы, к которым не было доступа в течение определенного времени.Однако PHP не гарантирует, что сессия будет уничтожена в течение этого времени.

Ваша долгосрочная стратегия сеанса должна работать нормально, но вы можете уменьшить ее на 1% до 0,1%

Еще одна вещь, на которую стоит обратить внимание, это то, что операционная система может очистить вашПапка / tmp во время перезагрузки, так что даже если PHP этого не сделает.

7 голосов
/ 20 октября 2011

в прошлый раз, когда я смотрел на источник каждый вызов метода session_start (), так сказать, «бросал кости», используя делитель и вероятность. Если вы нажмете, то он удалит все файлы из каталога session.save_path, которые были старше session.gc_maxlifetime. Я забыл, использовал ли он время модификации или доступа к файлу, хотя это не должно иметь значения при обычных обстоятельствах, потому что php перезаписывает файл сеанса по умолчанию в конце выполнения скрипта, поэтому мод и время доступа почти всегда должны очень близко совпадать.

// Rough psuedo code of how php's session_start() function works regarding garbage collection.
function session_start() {
    $percentChanceToGC = 100 * ini_get('session.gc_probability') / ini_get('session.session.gc_divisor');
    $shouldDoGarbageCollection = rand(1, 100) < $percentChanceToGC;
    if ($shouldDoGarbageCollection) {
        $expiredCutoffTime = time() - ini_get('session.gc_maxlifetime');
        foreach (scandir(ini_get('session.save_path')) as $sessionFile) {
            if (filemtime($sessionFile) < $expiredCutoffTime) {
                unlink($sessionFile);
            }
        }
    }

    // ... rest of code ....
}

Я не знаю, сколько файлов сессий у вас останется, если вы хотите, чтобы они жили как минимум 6 месяцев. Учтите, что php может понадобиться некоторое время для определения многих тысяч файлов, чтобы определить их возраст. Возможно рассмотрим другие варианты долговременного хранения этих данных. Или вы можете отключить php gc и просто запустить задание cron для удаления устаревших файлов сеанса. В противном случае этот 1% запросов будет вызывать gc и ждать php; другими словами, это может отставать.

2 голосов
/ 20 октября 2011

Я не эксперт в этом, но прочитав руководство, я бы обратил ваше внимание на другую настройку, session.gc_maxlifetime. Из документов:

session.gc_maxlifetime указывает количество секунд, по истечении которых данные будут рассматриваться как «мусор» и потенциально очищаться. Сборка мусора может происходить во время запуска сеанса (в зависимости от session.gc_probability и session.gc_divisor).

Таким образом, если вы установите для этого параметра подходящее значение (60 * 60 * 24 * 365 / 2 в течение полугода, то есть 15768000), то соответствующие данные не будут подходить для сбора мусора, независимо от того, каковы другие параметры.

...