Laravel возможная проблема сборщика мусора: сессии истекают случайно

У меня есть веб-приложение, которое использует Laravel 4.2 с драйвером файла сеанса. Он работает по протоколу https, и все пользователи хранятся в одной базе данных. Мы получаем много сообщений о том, что пользователи случайно выходят из системы, но я не могу воспроизвести проблему в нашей среде разработки. Я подозреваю, что сборщик мусора может очищать неправильные файлы сессии или что-то в этом роде? Должны ли мы переключиться на хранилище сеансов базы данных?

Вот некоторые из наших настроек сеанса:

'lifetime' => 720,
'expire_on_close' => false,
'lottery' => array(2, 100), 

наш php.ini имеет gc_maxlifetime установлен в 43200,

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

Благодарю за любую помощь!

1 ответ

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

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

Таким образом, вместо того, чтобы принимать запросы каждой страницы пользователя для запуска SQL-запроса к

      DELETE FROM sessions WHERE lastactivity < [session_time]

По умолчанию 2 в лотерее 100 гарантирует, что это произойдет во время случайных HTTP-запросов за счет какого-то незадачливого посетителя по цене в среднем в десятую миллисекунду.

Вы можете увидеть в промежуточном программном обеспечении StartSession , где оно очищает сеансы, используя метод collectGarbage , который очищает сеанс на основе конфигурации лотереи (выше).

https://github.com/illuminate/session/blob/master/Middleware/StartSession.php

Конфигурации по умолчанию: [2, 100]. Это означает, что выбирается случайное целое число от 1 до 100, если оно меньше или равно 2, кэш будет очищен. (Так же у вас, как у посетителя, есть 2%-ная возможность очистки кеша при каждом звонке).

Вы можете улучшить это, если считаете, что это то, что происходит с командой php artisan, которую вы помещаете в Kernel.php.

      <?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Session; //for sake of simplicity I am assuming this exists

class PruneExpiredSessions extends Command
{
    
    protected $signature = 'sessions:prune';

    protected $description = 'Override default DB Session garbage collection';

    public function handle()
    {

        Session::where('last_activity',< time()-(60*60*48))->delete();
        $this->info('Successfully deleted Expired Sessions' );
        return Command::SUCCESS;
    }
}

Теперь просто в app/console/kernel.php

      <?php

namespace App\Console; 

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')->hourly();
        $schedule->command('telescope:prune --hours=48')->daily();
        $schedule->command('session:prune')->daily(); <--This is the line
    }
 ...
}

Просто не забудьте добавитьк запланированным задачам/заданиям Cron вашей ОС каждую минуту

Другие вопросы по тегам