商業,創業,美食,葡萄酒,閱讀,網路科技。
這是我的 FB粉專 以及 IG,我比較常使用 Threads,歡迎大家追蹤互動~
圖片來源 https://github.com/laravel/laravel
******* 以下是以 Laravel 5.5 而言 *******
Queues
https://laravel.com/docs/5.5/queues
首先請看 config/queue.php
,裡面 connections 選項有 database, redis 等選項,知道有這些選項就可以了,這部分我們不用動。一般使用 database 當 driver,將 .env
中的 QUEUE_DRIVER=database
. QUEUE_DRIVER 預設是 sync, 注意當 QUEUE_DRIVER=sync
時基本上他就不是 queue, 在 loading page 時可以明顯感到他是 sync 在工作。
如果你是用 QUEUE_DRIVER=database
, 要執行
php artisan queue:table
php artisan migrate
會在 DB 裡生成一 jobs table. 執行
php artisan make:job YourQueueJobClassName
會在 app/Jobs
底下新增 YourQueueJobClassName.php
(本來不存在 app/Jobs
資料夾)
class YourQueueJobClassName
基本上有兩個 function:constructor
和 handle
. 如官方教程範例
class ProcessPodcast implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $podcast;
/**
* Create a new job instance.
*
* @param Podcast $podcast
* @return void
*/
public function __construct(Podcast $podcast)
{
$this->podcast = $podcast;
}
/**
* Execute the job.
*
* @param AudioProcessor $processor
* @return void
*/
public function handle(AudioProcessor $processor)
{
// Process uploaded podcast...
}
}
這裡使用 dependency injection pattern. 在 constructor type-hint / inject 進來,用 local 變數接住,然後在 function handle 做事。
把 dependency injection 跟 function handle 寫完之後,queue job 的內容就完成了。在觸發 queue job 的地方使用 dispatch helper
dispatch(new ProcessPodcast($podcast));
注意,到此為止你的工作只會被寫到 DB jobs table, 並不會被執行。你需要啟動 queue worker process. 官方教程建議安裝 supervisor 套件,安裝好之後執行 service supervisor restart
, 之後就依照官方教程編輯 laravel-worker.conf
(以 Ubuntu 來說路徑是 /etc/supervisor/conf.d/laravel-worker.conf
)
laravel-worker.conf
中的 command 要換成你專案的路徑,queue:work sqs
要換成 queue:work database
(如果你的 .env
QUEUE_DRIVER=database
), user 欄位要換成你的 user name, stdout_logfile
要換成你專案的路徑。
編輯好 laravel-worker.conf
後執行
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
這樣一個 queue 系統就可以運行了。
Task Scheduling
https://laravel.com/docs/5.5/scheduling
首先將底下這行加到 server 的排程 (crontab -e)
* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
可以直接在 App\Console\Kernel
中的 schedule method 寫你的 scheduled tasks
$schedule->call(function () {
// ...
})->daily(); // 每日
教程提到,你也可以排程 artisan commands 或是作業系統 commands. 如何寫你的 artisan commands 呢?
https://laravel.com/docs/5.5/artisan#generating-commands
如教程例子,執行
php artisan make:command SendEmails
他會在 app/Console/Commands
新增 SendEmails.php
(Commands folder 預設是不存在)。SendEmails.php
中先編輯 signature, description 兩個變數,這兩個變數就是 command name 和 description. 確認你的 App\Console\Kernel
commands method 是否如下
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
如果是的話,所有在 app/Console/Commands
底下的 command 都會被自動註冊,包含我們剛剛新增的 command.
這樣 php artisan list
就會看到你剛寫的 command, signature, description. 接著可以開始編輯你的 command 的工作內容,以上方範例而言:SendEmails
. 教程有一段
“For greater code reuse, it is good practice to keep your console commands light and let them defer to application services to accomplish their tasks. In the example below, note that we inject a service class to do the “heavy lifting” of sending the e-mails.”
盡量把工作內容寫在 service 裡而不是全寫在 command 裡。好處是 1. 工作內容可以較好的模組化 2. 一些內部 class (例如 ORM classes) 不會直接被 command access, 多一層保護與檢查。
除了 define command class 外,另外也可以 define Closure Commands. 在 App\Console\Kernel
, commands method 會 load routes/console.php
. routes/console.php
中預設
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->describe('Display an inspiring quote');
這就是 Closure Command 的範例,如果嫌上方新增 command class 麻煩,也可以參考這個 command inspire, 直接寫在 routes/console.php
裡。
在 App\Console\Kernel
schedule method 打開 $schedule->command('inspire')
這個 inspire command 就會被執行。
以上大概就是 scheduled tasks 跟 custom artisan command 的部分~
商業,創業,美食,葡萄酒,閱讀,網路科技。