Laravel 定時任務,避免重複的方法-----使用檔案鎖

__中國人發表於2018-12-13
有時一個預定的工作需要比我們最初預期的更多的時間執行,這樣會導致另外一個工作的例項開始,而第一個還沒有完成,例如,我們執行一個每分鐘生成報告的工作有時候當資料變大時,報表生成可能需要 1 分鐘以上,這樣就可以在第一個還在進行時啟動該作業的另一個例項。

在大多數情況下,這是很好的,但有時候應該防止這種情況,以保證正確的資料或防止高的伺服器資源消耗,所以讓我們看看如何防止這種情況在 laravel 中發生: $schedule->command('mail:send')->withoutOverlapping(); Laravel 將檢查 Console\Scheduling\Event::withoutOverlapping 類屬性,如果設定為 true,它將嘗試為作業建立互斥,並且只有在建立互斥的情況下才能執行該作業。 但是上面是互斥?這是我可以在網上找到最有趣的解釋: 當我在工作中進行熱烈的討論時,我使用一隻橡膠雞,我在這樣的場合放在桌子上。 持有雞的人是唯一被允許談話的人。 如果你不握雞,你不會說話。 你只能指示你想要雞,等到你說話之前才能得到它。 一旦你完成演講,你可以將雞回到主持人,他將把它交給下一個人說話。 這樣可以確保人們互不說話,也有自己的空間。 用線替換雞與互斥和人,你基本上有一個互斥的概念。 –https://stackoverflow.com/questions/34524/what-is-a-mutex/34558#34558 所以當作業第一次啟動時,Laravel 建立一個互斥,然後每次作業執行時,它檢查互斥是否存在,只有在沒有工作的情況下執行。這裡是 withoutOverlapping 方法中做的事 ``public function withoutOverlapping() { $this->withoutOverlapping = true; return $this->then(function () { $this->mutex->forget($this); })->skip(function () { return $this->mutex->exists($this); }); } `` 因此,Laravel 建立一個 filter-callback 方法,指示 Schedule Manager 忽略任務,如果互斥仍然存在,它還會建立一個在完成任務例項後清除互斥的回撥。 在執行該作業之前,Laravel 會在Console\Scheduling\Event::run()方法中進行以下檢查: ``if ($this->withoutOverlapping && ! $this->mutex->create($this)) { return; }`` 互斥體屬性來自哪裡? 當 Console\Scheduling\Schedule 的例項被例項化時,laravel 會檢查 Console\Scheduling\Mutex 介面的實現是否繫結到容器,如果是,則使用該例項,如果不是,使用Console\Scheduling\CacheMutex例項: ``$this->mutex = $container->bound(Mutex::class) ? $container->make(Mutex::class) $container->make(CacheMutex::class); 現在,Schedule Manager 正在註冊你的事件,它會傳遞互斥的一個例項: $this->events[] = new Event($this->mutex, $command); 預設情況下,Laravel 使用基於快取的互斥,但您可以覆蓋它並實現自己的互斥方法並將其繫結到容器。 基於快取的互斥 CacheMutex 類包含 3 個簡單的方法,它使用事件互斥名作為快取鍵: public function create(Event $event)
{
return $this->cache->add($event->mutexName(), true, 1440);
} public function exists(Event $event) { return $this->cache->has($event->mutexName()); } public function forget(Event $event)
{
$this->cache->forget($event->mutexName());
} ###任務完成後的互斥刪除 如前所述,管理器註冊一個在完成任務之後刪除互斥的回撥,對於在作業系統上執行命令的任務可能足以確保互斥被清除,但是對於回撥 執行回撥時指令碼可能會當機,所以為了防止這種情況在 `Console\Scheduling\CallbackEvent::run()`中新增了一個額外的回退: register_shutdown_function(function () {
$this->removeMutex();
});``

刻意練習,每日精進

相關文章