摘要:持有雞的人是唯一被允許談話的人。這樣可以確保人們互不說話,也有自己的空間。所以當作業第一次啟動時,創建一個互斥,然后每次作業運行時,它檢查互斥是否存在,只有在沒有工作的情況下運行。
譯文GitHub https://github.com/yuansir/diving-laravel-zh
原文鏈接 https://divinglaravel.com/task-scheduling/preventing-overlapping
Sometimes a scheduled job takes more time to run than what we initially expected, and this causes another instance of the job to start while the first one is not done yet, for example imagine that we run a job that generates a report every minute, after sometime when the data gets huge the report generation might take more than 1 minute so another instance of that job starts while the first is still ongoing.
有時一個預定的工作需要比我們最初預期的更多的時間運行,這樣會導致另外一個工作的實例開始,而第一個還沒有完成,例如,我們運行一個每分鐘生成報告的工作有時候當數據變大時,報表生成可能需要1分鐘以上,這樣就可以在第一個還在進行時啟動該作業的另一個實例。
In most scenarios this is fine, but sometimes this should be prevented in order to guarantee correct data or prevent a high server resources consumption, so let"s see how you can prevent such scenario in laravel:
在大多數情況下,這是很好的,但有時候應該防止這種情況,以保證正確的數據或防止高的服務器資源消耗,所以讓我們看看如何防止這種情況在laravel中發生:
$schedule->command("mail:send")->withoutOverlapping();
Laravel will check for the ConsoleSchedulingEvent::withoutOverlapping class property and if it"s set to true it"ll try to create a mutex for the job, and will only run the job if creating a mutex was possible.
Laravel將檢查 ConsoleSchedulingEvent::withoutOverlapping 類屬性,如果設置為true,它將嘗試為作業創建互斥,并且只有在創建互斥的情況下才能運行該作業。
But what"s a mutex? 但是上面是互斥?Here"s the most interesting explanation I could find online:
這是我可以在網上找到最有趣的解釋:
When I am having a big heated discussion at work, I use a rubber chicken which I keep in my desk for just such occasions. The person holding the chicken is the only person who is allowed to talk. If you don"t hold the chicken you cannot speak. You can only indicate that you want the chicken and wait until you get it before you speak. Once you have finished speaking, you can hand the chicken back to the moderator who will hand it to the next person to speak. This ensures that people do not speak over each other, and also have their own space to talk. Replace Chicken with Mutex and person with thread and you basically have the concept of a mutex.-- https://stackoverflow.com/questions/34524/what-is-a-mutex/34558#34558
當我在工作中進行熱烈的討論時,我使用一只橡膠雞,我在這樣的場合放在桌子上。 持有雞的人是唯一被允許談話的人。 如果你不握雞,你不會說話。 你只能指示你想要雞,等到你說話之前才能得到它。 一旦你完成演講,你可以將雞回到主持人,他將把它交給下一個人說話。 這樣可以確保人們互不說話,也有自己的空間。 用線替換雞與互斥和人,你基本上有一個互斥的概念。
-- https://stackoverflow.com/questions/34524/what-is-a-mutex/34558#34558
So Laravel creates a mutex when the job starts the very first time, and then every time the job runs it checks if the mutex exists and only runs the job if it doesn"t.
所以當作業第一次啟動時,Laravel創建一個互斥,然后每次作業運行時,它檢查互斥是否存在,只有在沒有工作的情況下運行。
Here"s what happens inside the withoutOverlapping method:
這里是 withoutOverlapping 方法中做的事
public function withoutOverlapping() { $this->withoutOverlapping = true; return $this->then(function () { $this->mutex->forget($this); })->skip(function () { return $this->mutex->exists($this); }); }
So Laravel creates a filter-callback method that instructs the Schedule Manager to ignore the task if a mutex still exists, it also creates an after-callback that clears the mutex after an instance of the task is done.
因此,Laravel創建一個filter-callback方法,指示Schedule Manager忽略任務,如果互斥仍然存在,它還會創建一個在完成任務實例后清除互斥的回調。
Also before running the job, Laravel does the following check inside the ConsoleSchedulingEvent::run() method:
在運行該作業之前,Laravel會在ConsoleSchedulingEvent::run()方法中進行以下檢查:
if ($this->withoutOverlapping && ! $this->mutex->create($this)) { return; }Where does the mutex property come from? 互斥體屬性來自哪里?
While the instance of ConsoleSchedulingSchedule is being instantiated, laravel checks if an implementation to the ConsoleSchedulingMutex interface was bound to the container, if yes it uses that instance but if not it uses an instance of ConsoleSchedulingCacheMutex:
當 ConsoleSchedulingSchedule 的實例被實例化時,laravel會檢查 ConsoleSchedulingMutex 接口的實現是否綁定到容器,如果是,則使用該實例,如果不是,使用ConsoleSchedulingCacheMutex實例:
$this->mutex = $container->bound(Mutex::class) ? $container->make(Mutex::class) : $container->make(CacheMutex::class);
Now while the Schedule Manager is registering your events it"ll pass an instance of the mutex:
現在,Schedule Manager正在注冊你的事件,它會傳遞互斥的一個實例:
$this->events[] = new Event($this->mutex, $command);
By default Laravel uses a cache-based mutex, but you can override that and implement your own mutex approach & bind it to the container.
默認情況下,Laravel使用基于緩存的互斥,但您可以覆蓋它并實現自己的互斥方法并將其綁定到容器。
The cache-based mutex 基于緩存的互斥The CacheMutex class contains 3 simple methods, it uses the event mutex name as a cache key:
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()); }Mutex removal after task finishes 任務完成后的互斥刪除
As we"ve seen before, the manager registers an after-callback that removes the mutex after the task is done, for a task that runs a command on the OS that might be enough to ensure that the mutex is cleared, but for a callback task the script might die while executing the callback, so to prevent that an extra fallback was added in ConsoleSchedulingCallbackEvent::run():
如前所述,管理器注冊一個在完成任務之后刪除互斥的回調,對于在操作系統上運行命令的任務可能足以確保互斥被清除,但是對于回調 執行回調時腳本可能會死機,所以為了防止這種情況在 ConsoleSchedulingCallbackEvent::run()中添加了一個額外的回退:
register_shutdown_function(function () { $this->removeMutex(); });
轉載請注明:?轉載自Ryan是菜鳥 | LNMP技術棧筆記
如果覺得本篇文章對您十分有益,何不 打賞一下
本文鏈接地址:?剖析Laravel計劃任務--避免重復
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/23237.html
摘要:表示該工作應該在每個月日上午運行這里還有一些其他的示例表示工作應該在星期三每分鐘運行一次。表示該工作應該每天在凌晨點和點運行兩次。方法調用的實例作為唯一的參數,這是用于記錄您提供的作業的計劃任務管理器,并決定每次守護進程應該運行什么。 譯文GitHub https://github.com/yuansir/diving-laravel-zh 原文鏈接 https://divinglar...
摘要:所以在這里創建一個事件的兩個實際方法是通過調用或,第一個提交一個的實例,后者提交來做一些特殊處理。那么會用表達式檢查命令是否到期嗎恰恰相反,使用庫來確定命令是否基于當前系統時間相對于我們設置的時區。 譯文GitHub https://github.com/yuansir/diving-laravel-zh 原文鏈接 https://divinglaravel.com/task-sche...
摘要:譯文原文鏈接在啟動計劃任務的事件的時候,的進度管理器在對象上調用方法,表示該事件發生在內。在方法里面定義每一個命令的互斥所以它是事件的表達式和命令字符串的組合。 譯文GitHub https://github.com/yuansir/diving-laravel-zh 原文鏈接 https://divinglaravel.com/task-scheduling/building-and...
摘要:也就是說,這僅僅是計劃在未來某一個時間執行某個任務,并不能保證精確的時間。重復執行問題這個方法執行時僅當沒有該計時器的其他代碼示例時才進行下一輪的執行。這樣的規則就會導致某些間隔會被跳過,同時多個間隔可能比預期時間要短。 寫在前面,最近在準備校招,陸陸續續做一些之前的總結,寫了一個小系列的文章,想借此機會記錄下來,也能以后有個地方能進行查閱,上一篇文章在css基礎總結希望能幫助一下和我...
摘要:高性能高精度定時服務,輕松管理千萬級定時任務。支持任務到期觸發和。支持創建延時任務和定時到期任務,和原生保持相同接口,輕松使用。不支持任務輸出任務鉤子及維護模式。是不指定任務名時自動生成,每個任務名必須唯一,相同任務名重復定義將會自動覆蓋。 Forsun高性能高精度定時服務,輕松管理千萬級定時任務。 定時服務項目地址:https://github.com/snower/forsun l...
閱讀 3228·2021-11-15 11:37
閱讀 2449·2021-09-29 09:48
閱讀 3814·2021-09-22 15:55
閱讀 3014·2021-09-22 10:02
閱讀 2636·2021-08-25 09:40
閱讀 3225·2021-08-03 14:03
閱讀 1691·2019-08-29 13:11
閱讀 1570·2019-08-29 12:49