laravel withoutOverlapping導致執行腳本延遲或者失效問題


2021年7月15日11:24:00

 

當執行某個需要經常跑的 everyMinute的之后防止,一次腳本未執行完就又重新跑,導致出現超出預期的錯誤,或者數據錯誤,就會使用 withoutOverlapping來防止重復執行

$schedule->command('NoPersonPrize')->everyMinute()->withoutOverlapping();

但是當你有多個withoutOverlapping和多個沒有使用withoutOverlapping的放在Kernel的時候,會出現一些意外,比如有些腳本沒有跑,或者延遲跑,是什么原因造成的呢?

 

 public function withoutOverlapping($expiresAt = 1440)
    {
        $this->withoutOverlapping = true;

        $this->expiresAt = $expiresAt;

        return $this->then(function () {
            $this->mutex->forget($this);
        })->skip(function () {
            return $this->mutex->exists($this);
        });
    }
withoutOverlapping的底層是利用緩存指定一個互斥的鎖,如果你的laravel的緩存使用redis的時候,就會使用redis作為互斥鎖的緩存key,默認緩存是file

$schedule->command('a')->everyMinute()->withoutOverlapping();

$schedule->command('b')->everyMinute();

$schedule->command('c')->everyMinute();

$schedule->command('d')->everyMinute()->withoutOverlapping();

 

這里多數人認為a,b,c,d會在每分鍾開始會同事執行,其實不是,是先執行a,|(b,c)|d,是在a執行完在執行d,(b,c)是和a基本同時執行,

問題在於在互斥鎖的問題,是執行一個完成之后在執行一個,不是每個腳本獨立執行的

舉例:

laravel_cache:framework/schedule-0e06f675a49cb9a0010858533b27d6a525caea88

內容:b:1;

 

 

就會導致延遲執行某些腳本,甚至不執行
使用建議如下:
1,沒有使用withoutOverlapping,在使用的上面,隔離開例如
$schedule->command('b')->everyMinute();
$schedule->command('c')->everyMinute();
#-------------------------------------------------------------------------
$schedule->command('a')->everyMinute()->withoutOverlapping();
$schedule->command('d')->everyMinute()->withoutOverlapping();

2,如果非必要每分鍾執行的腳本,不要使用everyMinute+withoutOverlapping這種組合,避免重復執行
建立通過代碼邏輯規避這個問題

3,如果多個有withoutOverlapping或者沒有withoutOverlapping可以通過->dailyAt('18:33');
這中類似的特殊時間避開全部整點執行問題

4,減少或者不用withoutOverlapping



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM