پاک کردن سشنهای منقضی در لاراول با زمانبند
خلاصهٔ کاملتر
اگه اپ لاراولتون از درایور سشن database یا file استفاده میکنه، سشنهای منقضی تو دیتابیس یا روی دیسک میمونن تا خود لاراول پاکشون کنه. از نسخهٔ 13.39 یه دستور جدید به اسم session:garbage-collect اضافه شده که میشه گذاشتش تو زمانبند (scheduler). Paul Redmond تو این مقاله توضیح میده چرا این کار بهتر از روش قبلیه.
Schedule::command('session:garbage-collect')->hourly();روش قبلی اسمش lottery هست، یعنی یه قرعهکشی که تو config/session.php تنظیم میشه. مقدار پیشفرض [2, 100] یعنی هر درخواستی که سشن باز میکنه ۲ درصد شانس داره که پاکسازی رو اجرا کنه، و اون درخواست باید صبر کنه تا کار تموم بشه. مشکل اینجاست که این شانس به ترافیک ربطی نداره: با هزار درخواست در دقیقه حدود ۲۰ بار در دقیقه delete اجرا میشه و ممکنه با هم تداخل کنن، ولی با ۴۰ درخواست در روز شاید حتی روزی یه بار هم اجرا نشه.
نویسنده پیشنهاد میکنه بعد از زمانبندی دستور، عدد اول lottery رو صفر کنید ([0, 100]) تا دیگه هیچ درخواست وبی پاکسازی رو اجرا نکنه. اگه همون [2, 100] بمونه چیزی خراب نمیشه، فقط کوئری اضافه میخوره. درایورهای redis، memcached، dynamodb، apc و cookie اصلاً به این دستور نیاز ندارن، چون سشنها خودشون با TTL (یعنی زمان انقضای خودکار) منقضی میشن یا تو مرورگر میمونن.
یه نکتهٔ مهم: کاربر حتی قبل از پاکسازی هم نمیتونه سشن منقضی رو بارگذاری کنه، چون هر دو درایور موقع خوندن سن سشن رو چک میکنن. پس این پاکسازی فقط فضای ذخیرهسازی رو آزاد میکنه. دستور از درایور پیشفرض و مقدار session.lifetime استفاده میکنه، گزینهای برای تغییرشون نداره و تعداد سشنهای پاکشده رو هم چاپ نمیکنه. برای lifetime پیشفرض ۱۲۰ دقیقه، اجرای ساعتی منطقیه.
اگه چندتا سرور دارید و درایور database هست، با onOneServer() کاری کنید فقط یه سرور delete رو اجرا کنه؛ این متد یه کش مشترک برای قفل لازم داره. ولی با درایور file هر سرور فایلهای خودشو داره، پس دستور باید روی همهٔ سرورها اجرا بشه، مگه اینکه پوشهٔ سشنها روی فضای مشترک باشه. برای نسخههای قبل از 13.39 هم میشه یه closure زمانبندی کرد که متد gc() هندلر سشن رو صدا میزنه؛ این روش روی لاراول 11 تا 13 جواب میده و قبل از onOneServer() حتماً باید name() داشته باشه.
نکات کلیدی:
- دستور session:garbage-collect از لاراول 13.39 در دسترسه.
- فقط برای درایورهای database و file کاربرد داره.
- lottery پیشفرض [2, 100] هست و بعد از زمانبندی بهتره بشه [0, 100].
- برای lifetime پیشفرض ۱۲۰ دقیقه، اجرای hourly() پیشنهاد شده.
- با چند سرور و درایور database از onOneServer() استفاده کنید، ولی با درایور file نه.
- تو closure نسخههای قدیمی، session.lifetime به دقیقهست و باید ضربدر ۶۰ بشه چون gc() ثانیه میگیره.




