laravel默認提供了一個命令定時任務的功能,在其餘的php框架下面,沒有這個定時任務,咱們要跑一些異步腳本怎麼操做呢,只能依賴咱們系統提供的crontab來作,這就致使咱們每次發版本新增定時任務都要去服務器更改crontab代碼,獲取更新這個配置。php
執行命令是php artisan schedule:run 來執行,那放在哪裏執行呢,沒錯這個調起仍是須要依賴咱們crontab來執行,可是隻須要配置一次,後續全部定時任務都在咱們業務代碼進行控制linux
咱們有一個導入數據的定時任務laravel
//每分鐘導入庫數據
$schedule->command(self::SIGNATURE)->withoutOverlapping()->everyMinute()->runInBackground();
複製代碼
這個任務在正常狀況下都是很是完美的,由於同一時刻只有一個再跑,跑完就能夠,可是一個場景出現git
有一天咱們的qa同窗剛部署環境後,咱們服務端就在默默的導入庫了,由於使用withoutOverlapping($expire_at=1440)這個時候在redis就有一個鎖產生了,這個默認帶參數是鎖的過時時間,默認是一天,而後由於咱們docker環境須要更改參數而後進行後端server服務的重啓,咱們重啓也是比較暴力,就是直接發送kill的信號,致使全部在裏面跑的進程瞬間kill,而這時候咱們的redis的鎖缺還存在,並且是1440分鐘左右,那當咱們server再啓動後,發現鎖一直存在,沒辦法進行後續的操做了,只能等着。github
說明:redis
代碼實現老是那麼蒼白無力哈,這裏就寫一個laravel的擴展來作,好處就是不影響咱們主體的任何代碼就完成了,咱們的laravel能夠隨意升級。docker
github地址:github.com/zzh78727258…shell
composer地址:packagist.org/packages/ze…後端
public function subscribe($events)
{
$events->listen(
[
CommandStarting::class, // 命令開始的時候
],
__CLASS__ . '@handle'
);
}
複製代碼