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
}
...
}
Просто не забудьте добавить