譯文GitHub https://github.com/yuansir/diving-laravel-zhphp
原文連接 https://divinglaravel.com/task-scheduling/before-the-divelinux
Imagine this scenario, as a developer of a large SaaS you're tasked with finding a way to select 10 random customers every minute during the weekend and offer them a discounted upgrade, the job for sending the discount can be pretty easy but we need a way to run it every minute, for that let me share a brief introduction about CRON for those who're not familiar with it.laravel
想象這種狀況,做爲一個大型SaaS的開發者,您須要找到一種在週末每分鐘選擇10個隨機客戶的方式,並提供折扣升級,發送折扣的工做可能很是簡單,但咱們須要每分鐘運行一次,爲此我分享一些CRON的簡要介紹給還不熟悉人。git
CRON is a daemon that lives inside your linux server, it's not awake most of the time but every minute it'll open its eyes and see if it's time to run any specific task that was given to it, you communicate with that daemon using crontab files, in most common setups that file can be located at /etc/crontab
, here's how a crontab file might look like:github
CRON是一個守護進程,它駐留在你的linux服務器中,大部分時間都沒有喚醒,可是每一分鐘它都會睜開雙眼,看看是否運行任何給定的任務,你使用crontab文件與該守護進程通訊,在大多數常見的設置文件能夠位於/etc/crontab
,crontab文件可能看起來像這樣:bootstrap
0 0 1 * * /home/full-backup 0 0 * * * /home/partial-backup 30 5 10 * * /home/check-subscriptions
In the crontab file each line represents a scheduled job, and each job definition contains two parts:數組
在crontab文件中,每行表示一個計劃任務做業,每一個做業定義包含兩部分:服務器
The 5 asterisks represent the following in order:app
5個星號按順序排列以下:dom
示例:
0 0 1 * *
in the first example indicates that the job should run on every month, at the first day of the month, at 12 AM, at the first minute of the hour. Or simply it should run every 1st day of the month at 12:00 AM.0 0 1 * *
在第一個例子中,表示該工做應在每個月,每月的第一個天,上午12點,每小時第一分鐘運行。 或者簡單地說,它應該在每個月的第一天上午12:00運行。0 * * * *
in the second example indicates that the job should run every hour.0 * * * *
在第二個例子中,表示該工做應該每小時運行一次。30 5 10 * *
indicates that the job should run on the 10th of every month at 5:30 AM30 5 10 * *
表示該工做應該在每月10日上午5:30運行Here are a few other examples:
* * * * 3
indicates that the job should run every minute on Wednesdays.* * * * 1-5
indicates that the job should run every minute Monday to Friday.0 1,15 * * *
indicates that the job should run twice a day at 1AM and 3PM.*/10 * * * *
indicates that the job should run every 10 minutes.這裏還有一些其餘的示例:
* * * * 3
indicates that the job should run every minute on Wednesdays.* * * * 3
表示工做應該在星期三每分鐘運行一次。* * * * 1-5
indicates that the job should run every minute Monday to Friday.* * * * 1-5
表示該工做應該每週一至週五運行。0 1,15 * * *
indicates that the job should run twice a day at 1AM and 3PM.0 1,15 * * *
表示該工做應該天天在凌晨1點和3點運行兩次。*/10 * * * *
indicates that the job should run every 10 minutes.*/10 * * * *
表示該工做應該每10分鐘運行一次。Yeah we can simply register this in our crontab file:
是的,咱們能夠在咱們的crontab文件中註冊:
* * * * php /home/divingLaravel/artisan send:offer
This command will inform the CRON daemon to run the php artisan send:offer
artisan command every minute, pretty easy right? But it then gets confusing when we want to run the command every minute only on Thursdays and Tuesdays, or on specific days of the month, having to remember the syntax for cron jobs is not an easy job and also having to update the crontab file every time you want to add a new job or update the schedule can be pretty time consuming sometimes, so a few releases back Laravel added some interesting feature that provides an easy to remember syntax for scheduling tasks:
該命令將通知CRON守護程序每分鐘運行 php artisan send:offer
artisan命令,是否是很容易? 可是,當咱們想要在星期四和星期二或每一個特定日子裏每分鐘運行命令時會感到困惑,記住cron做業的語法不是一件容易的事,並且還須要更新crontab文件,你想添加一個新的工做或更新的時間表多是至關耗時的時間,因此幾個版本發佈後Laravel添加了一些有趣的功能,爲調度任務提供了一個容易記住的語法:
$schedule->command('send:offer') ->everyFiveMinutes() ->wednesdays();
You only have to register one cron jobs in your crontab and laravel takes care of the rest under the hood:
你只須要在你的crontab中註冊一個cron工做,laravel會處理剩下的事:
* * * * * php /divingLaravel/artisan schedule:run >> /dev/null 2>&1
You may define your scheduled commands inside the schedule method of your App\Console\Kernel
class:
您能夠在App\Console\Kernel
類的schedule方法中定義預約的命令:
protected function schedule(Schedule $schedule) { $schedule->command('send:offer') ->everyFiveMinutes() ->wednesdays(); }
If you'd like more information about the different Timer options, take a look at the official documentation.
若是您想了解有關不一樣計時器選項的更多信息,請查看 官方文檔。
While the Console Kernel instance is being instantiated, Laravel registers a listener to the Kernel's booted
event that binds the Scheduler to the container and calls the schedule() method of the kernel:
當Console Kernel被實例化時,Laravel向內核的booted
事件註冊一個偵聽器,該事件將Scheduler綁定到容器並調用kernel的schedule()方法:
// in Illuminate\Foundation\Console\Kernel public function __construct(Application $app, Dispatcher $events) { $this->app->booted(function () { $this->defineConsoleSchedule(); }); } protected function defineConsoleSchedule() { // Register the Scheduler in the Container $this->app->instance( Schedule::class, $schedule = new Schedule($this->app[Cache::class]) ); // Call the schedule() method that we override in our App\Console\Kernel $this->schedule($schedule); }
This booted
event is fired once the console kernel finishes the bootstrapping sequence defined in the Kernel class.
一旦console kernel完成Kernel類中定義的引導順序,這個booted
事件就被觸發。
Inside the handle() method of the Kernel, Laravel checks if FoundationApplication was booted before, and if not it calls the bootstrapWith() method of the Application and passes the bootstrappers array defined in the console Kernel.
在Kernel的handle()方法中,Laravel會檢查Foundation\Application
是否已啓動,若是不是調用應用程序的bootstrapWith()方法,並傳遞在console Kernel定義的引導程序數組。
When the CRON daemon calls the php artisan schedule:run
command every minute, the Console Kernel will be booted up and the jobs you defined inside your App\Console\Kernel::schedule()
method will be registered into the scheduler.
當CRON守護程序每分鐘都調用php artisan schedule:run
命令時,控制檯Console Kernel將被啓動,您在App\Console\Kernel::schedule()
方法中定義的做業將被註冊到調度程序。
The schedule()
method takes an instance of Illuminate\Console\Scheduling\Schedule
as the only argument, this is the schedule manager used to record the jobs you give it and decides what should run every time the CRON daemon pings it.
schedule()
方法調用Illuminate\Console\Scheduling\Schedule
的實例做爲惟一的參數,這是用於記錄您提供的做業的計劃任務管理器,並決定每次CRON守護進程應該運行什麼。
轉載請註明: 轉載自Ryan是菜鳥 | LNMP技術棧筆記
若是以爲本篇文章對您十分有益,何不 打賞一下
本文連接地址: 剖析Laravel計劃任務--初探