摘要:譯文原文鏈接在啟動(dòng)計(jì)劃任務(wù)的事件的時(shí)候,的進(jìn)度管理器在對(duì)象上調(diào)用方法,表示該事件發(fā)生在內(nèi)。在方法里面定義每一個(gè)命令的互斥所以它是事件的表達(dá)式和命令字符串的組合。
譯文GitHub https://github.com/yuansir/diving-laravel-zh
原文鏈接 https://divinglaravel.com/task-scheduling/building-and-running-the-os-command
When it"s time to fire a scheduled event, Laravel"s schedule manager calls the run() method on the IlluminateConsoleSchedulingEvent object representing that event, this happens inside the IlluminateConsoleSchedulingScheduleRunCommand.
在啟動(dòng)計(jì)劃任務(wù)的事件的時(shí)候,Laravel的進(jìn)度管理器在IlluminateConsoleSchedulingEvent對(duì)象上調(diào)用 run() 方法,表示該事件發(fā)生在 IlluminateConsoleSchedulingScheduleRunCommand 內(nèi)。
This run() method builds the command syntax and runs it on the operating system using the Symfony Process component, but before building the command it first checks if the command should be running in the background, by default all commands run in the foreground unless you use the following method while scheduling your command:
這個(gè) run() 方法構(gòu)建命令語法,并使用Symfony Process組件在操作系統(tǒng)上運(yùn)行它,但在構(gòu)建命令之前,它首先檢查該命令是否應(yīng)該在后臺(tái)運(yùn)行,默認(rèn)情況下所有命令都在前臺(tái)運(yùn)行 除非你使用以下方法來調(diào)度命令:
->runInBackground()When do I need to run a command in the background? 什么時(shí)候我需要在后臺(tái)運(yùn)行命令?
Imagine if you have several tasks that should run at the same time, say every hour, with the default settings Laravel will instruct the OS to run the commands one by one:
假設(shè)如果您有幾個(gè)任務(wù)應(yīng)該同時(shí)運(yùn)行,比如每個(gè)小時(shí),Laravel默認(rèn)設(shè)置會(huì)指示操作系統(tǒng)逐個(gè)運(yùn)行命令:
~ php artisan update:coupons # Waiting for the command to finish # ... # Command finished, now we run the next one ~ php artisan send:mail
However, you can instruct the OS to run the commands in the background so that you can continue pushing more commands even if the other ones haven"t finished yet:
但是,你可以指示操作系統(tǒng)在后臺(tái)運(yùn)行命令,以便您可以繼續(xù)推送更多命令,即使其他命令尚未完成:
~ php artisan update:coupons & ~ php artisan send:mail &
Using the ampersand at the end of a command lets you continue pushing commands without having to wait for the initial ones to finish.
使用命令末尾的&符號(hào)可以繼續(xù)推送命令,而無需等待初始化完成。
The run() method checks the value of the runInBackground property and decides which method to call next, runCommandInForeground() or runCommandInBackground().
run() 方法檢查 runInBackground 屬性的值,并決定下一個(gè)調(diào)用哪個(gè)方法runCommandInForeground() 還是 runCommandInBackground()。
In case the command is to be run in the foreground the rest is simple:
如果命令要在前臺(tái)運(yùn)行,其余部分就簡(jiǎn)單了:
$this->callBeforeCallbacks($container); (new Process( $this->buildCommand(), base_path(), null, null, null ))->run(); $this->callAfterCallbacks($container);
Laravel executes any before-callbacks, sends the command to the OS, and finally executes any after-callbacks.
Laravel執(zhí)行任意before-callbacks,將命令發(fā)送到OS,最后執(zhí)行任意before-callbacks。
However, if the command is to run the background Laravel calls callBeforeCallbacks(), sends the command, but doesn"t call the after-callbacks, the reason is as you might think, because the command will be executed in the background so if we call callAfterCallbacks() at this point it won"t be running after the command finishes, it"ll run once the command is sent to the OS.
但是,如果命令是在后臺(tái)運(yùn)行Laravel調(diào)用 callBeforeCallbacks(),發(fā)送命令,但不調(diào)用after-callbacks,原因正如你所想的,因?yàn)樵撁顚⒃诤笈_(tái)執(zhí)行 如果我們?cè)谶@個(gè)時(shí)候調(diào)用 callAfterCallbacks() ,那么在命令完成之后,它將不會(huì)運(yùn)行,一旦命令被發(fā)送到操作系統(tǒng),它就會(huì)運(yùn)行。
So no after-callbacks are executed when we run commands in the background? 那么當(dāng)我們?cè)诤笈_(tái)運(yùn)行命令時(shí),沒有執(zhí)行after-callbacks?They run, laravel does that using another command that runs after the original one finishes:
他們運(yùn)行了,laravel在原來的一個(gè)命令完成后使用另一個(gè)命令運(yùn)行:
(php artisan update:coupons ; php artisan schedule:finish eventMutex) &
This command will cause a sequence of two commands to run one after another but in the background, so after your update:coupons command finishes a schedule:finish command will run given the Mutex of the current event, using this ID Laravel locates the event and runs its after-callbacks.
這個(gè)命令會(huì)導(dǎo)致一系列的兩個(gè)命令一個(gè)接一個(gè)地運(yùn)行,但在后臺(tái)運(yùn)行,所以在你的 update:coupons 命令完成一個(gè) schedule:finish 命令后,會(huì)運(yùn)行給定當(dāng)前事件的 Mutex,使用這個(gè)ID Laravel 查找事件并運(yùn)行其回調(diào)。
Building the command string 構(gòu)建命令字符串When the scheduler calls the runCommandInForeground() or runCommandInBackground()methods, a buildCommand() is called to build the actual command that the OS will run, this method simply does the following:
當(dāng)調(diào)度程序調(diào)用 runCommandInForeground() 或 runCommandInBackground() 方法時(shí),調(diào)用一個(gè)buildCommand() 來構(gòu)建操作系統(tǒng)將運(yùn)行的實(shí)際命令,這個(gè)方法只需執(zhí)行以下操作:
return (new CommandBuilder)->buildCommand($this);
To build the command, the following configurations need to be known:
The command mutex
The location that output should be sent to
Determine if the output should be appended
The user to run the command under
Background vs Foreground
構(gòu)建命令,需要知道以下配置:
命令mutex
輸出應(yīng)發(fā)送到的位置
確定輸出是否應(yīng)該追加
運(yùn)行命令的用戶
后臺(tái)還是前臺(tái)
The command mutex 命令互斥A mutex is a unique ID set for every command, Laravel uses it mainly to prevent command overlapping which we will discuss later, but it also uses it as a unique ID for the command.
互斥是每個(gè)命令的唯一ID集合,Laravel主要使用它來防止命令重疊,我們稍后將討論,但它也將其用作命令的唯一ID。
Laravel defines the mutex of each command inside the Event::mutexName() method:
Laravel在 Event::mutexName() 方法里面定義每一個(gè)命令的互斥:
return "framework".DIRECTORY_SEPARATOR."schedule-".sha1($this->expression.$this->command);
So it"s a combination of the CRON expression of the event as well as the command string.
所以它是事件的CRON表達(dá)式和命令字符串的組合。
However, for callback events the mutex is created as follows:
但是,對(duì)于回調(diào)事件是這樣創(chuàng)建互斥的:
return "framework/schedule-".sha1($this->description);
So to ensure having a correct mutex for your callback event you need to set a description for the command:
所以為了確保你的回調(diào)事件有一個(gè)正確的互斥,你需要為命令設(shè)置一個(gè)描述:
$schedule->call(function () { DB::table("recent_users")->delete(); })->daily()->description("Clear recent users");Handling output 控制輸出
By default the output of commands is sent to /dev/null which is a special file that discards data written to it, however if you want to send the command output somewhere you can change that using the sendOutputTo() method while defining the command:
默認(rèn)情況下,命令的輸出被發(fā)送到 /dev/null ,這是一個(gè)寫入丟棄數(shù)據(jù)的特殊文件,但是如果你想在某個(gè)地方發(fā)送命令輸出,可以使用 sendOutputTo() 定義命令:
$schedule->command("mail:send")->sendOutputTo("/home/scheduler.log");
But this will cause the output to overwrite whatever is written to the scheduler.log file every time, to append the output instead you can use appendOutputTo(). Here"s how the command would look like:
但這會(huì)導(dǎo)致輸出覆蓋每次寫入 scheduler.log 文件的任何東西,如果用追加的方式輸出可以使用appendOutputTo()。 命令如下所示:
// Append output to file php artisan mail:send >> /home/scheduler.log 2>&1 // Overwrite file php artisan mail:send > /home/scheduler.log 2>&1
2>&1 instructs the OS to redirect error output to the standard output channel, in short words that means errors and output will be logged into your file.
2>&1 指示操作系統(tǒng)將錯(cuò)誤輸出重定向到標(biāo)準(zhǔn)輸出通道,簡(jiǎn)而言之,這意味著錯(cuò)誤和輸出將被記錄到您的文件中。
Using the correct user 使用正確的用戶When you set a user to run the command:
當(dāng)你設(shè)置一個(gè)用戶去執(zhí)行命令的時(shí)候:
$schedule->command("mail:send")->user("forge");
Laravel will run the command as follows:
Laravel會(huì)像下面這樣執(zhí)行命令:
sudo -u forge -- sh -c "php artisan mail:send >> /home/scheduler.log 2>&1"Running in the background 在后臺(tái)允許
As we discussed before, the command string will look like this in case it"s desired for it to run in the background:
As we discussed before, the command string will look like this in case it"s desired for it to run in the background:
正如我們之前討論過的,命令字符串將如下所示,它在后臺(tái)運(yùn)行:
(php artisan update:coupons ; php artisan schedule:finish eventMutex) &
But that"s just a short form, here"s the complete string that"ll actually run:
但這只是一個(gè)簡(jiǎn)短的形式,這里是完整的字符串,實(shí)際上可以運(yùn)行:
(php artisan update:coupons >> /home/scheduler.log 2>&1 ; php artisan schedule:finish eventMutex) > /dev/null 2>&1 &
Or this if you don"t set it to append output & didn"t define a custom destination:
或者如果您沒有將其設(shè)置為追加輸出,也沒有定義自定義輸出位置:
(php artisan update:coupons > /dev/null 2>&1 ; php artisan schedule:finish eventMutex) > /dev/null 2>&1 &Sending the output via email 通過郵件發(fā)送輸出
You can choose to send the command output to an email address using the emailOutputTo()method:
你可以通過調(diào)用 emailOutputTo() 方法來將命令輸出發(fā)送到電子郵件
$schedule->command("mail:send")->emailOutputTo(["myemail@mail.com", "myOtheremail@mail.com"]);
You can also use emailWrittenOutputTo() instead if you want to only receive emails if there"s an output, otherwise you"ll receive emails even if now output for you to see, it"ll be just a notification that the command ran.
如果有一個(gè)輸出,你只想接收電子郵件你也可以使用 emailWrittenOutputTo() ,否則你會(huì)收到電子郵件即使現(xiàn)在輸出給你你看到了,它也只是命令運(yùn)行一個(gè)通知。
This method will update the output property of the Scheduled Event and point it to a file in the storage/logs directory:
這個(gè)方法將更新計(jì)劃事件的輸出屬性并將其輸出到 storage/logs 目錄中的文件:
if (is_null($this->output) || $this->output == $this->getDefaultOutput()) { $this->sendOutputTo(storage_path("logs/schedule-".sha1($this->mutexName()).".log")); }
Notice that this will only work if you haven"t already set a custom output destination.
注意,只有在尚未設(shè)置自定義輸出目標(biāo)位置時(shí),此操作才會(huì)起作用。
Next Laravel will register an after-callback that"ll try to locate that file, read its content, and send it to the specified recipients.
接下來,Laravel將注冊(cè)一個(gè)回調(diào),嘗試找到該文件,讀取其內(nèi)容,并將其發(fā)送到指定的收件人。
$text = file_exists($this->output) ? file_get_contents($this->output) : ""; if ($onlyIfOutputExists && empty($text)) { return; } $mailer->raw($text, function ($m) use ($addresses) { $m->to($addresses)->subject($this->getEmailSubject()); });
轉(zhuǎn)載請(qǐng)注明:?轉(zhuǎn)載自Ryan是菜鳥 | LNMP技術(shù)棧筆記
如果覺得本篇文章對(duì)您十分有益,何不 打賞一下
本文鏈接地址:?剖析Laravel計(jì)劃任務(wù)--創(chuàng)建和運(yùn)行系統(tǒng)命令
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/23239.html
摘要:所以在這里創(chuàng)建一個(gè)事件的兩個(gè)實(shí)際方法是通過調(diào)用或,第一個(gè)提交一個(gè)的實(shí)例,后者提交來做一些特殊處理。那么會(huì)用表達(dá)式檢查命令是否到期嗎恰恰相反,使用庫來確定命令是否基于當(dāng)前系統(tǒng)時(shí)間相對(duì)于我們?cè)O(shè)置的時(shí)區(qū)。 譯文GitHub https://github.com/yuansir/diving-laravel-zh 原文鏈接 https://divinglaravel.com/task-sche...
摘要:持有雞的人是唯一被允許談話的人。這樣可以確保人們互不說話,也有自己的空間。所以當(dāng)作業(yè)第一次啟動(dòng)時(shí),創(chuàng)建一個(gè)互斥,然后每次作業(yè)運(yùn)行時(shí),它檢查互斥是否存在,只有在沒有工作的情況下運(yùn)行。 譯文GitHub https://github.com/yuansir/diving-laravel-zh 原文鏈接 https://divinglaravel.com/task-scheduling/pr...
摘要:表示該工作應(yīng)該在每個(gè)月日上午運(yùn)行這里還有一些其他的示例表示工作應(yīng)該在星期三每分鐘運(yùn)行一次。表示該工作應(yīng)該每天在凌晨點(diǎn)和點(diǎn)運(yùn)行兩次。方法調(diào)用的實(shí)例作為唯一的參數(shù),這是用于記錄您提供的作業(yè)的計(jì)劃任務(wù)管理器,并決定每次守護(hù)進(jìn)程應(yīng)該運(yùn)行什么。 譯文GitHub https://github.com/yuansir/diving-laravel-zh 原文鏈接 https://divinglar...
摘要:現(xiàn)在讓我們將這個(gè)命令通過使用命令進(jìn)行封裝,使其更易于運(yùn)行和可加入計(jì)劃任務(wù)。編寫備份任務(wù)的計(jì)劃任務(wù)首先,在中能夠輕松創(chuàng)建計(jì)劃任務(wù)。 譯文首發(fā)于 使用 Laravel 制定 MySQL 數(shù)據(jù)庫備份計(jì)劃任務(wù),轉(zhuǎn)載請(qǐng)注明出處。 你可以在終端里通過運(yùn)行一行命令導(dǎo)出整個(gè)數(shù)據(jù)庫。這種方案不僅簡(jiǎn)單直接而且有效。不過有更加自動(dòng)化的解決方案。讓我們來看看究竟是什么! showImg(https://seg...
閱讀 1323·2021-10-15 09:39
閱讀 3208·2021-09-10 10:50
閱讀 3554·2019-08-30 15:53
閱讀 1981·2019-08-30 15:52
閱讀 2646·2019-08-29 15:31
閱讀 2061·2019-08-26 13:43
閱讀 2706·2019-08-26 13:37
閱讀 1535·2019-08-23 18:31