尤川豪   ·  4年前
445 貼文  ·  275 留言

Laravel Queue 機制使用 database driver 的實作?

supervisor 的使用?

state 存在 database?

queue worker 是純 php process?什麼情況下會關閉、需要被 supervisor 重啟?

queue worker 處理 jobs 的頻率?

在 cronjob 下啟動 queue worker 時,處理 jobs 的頻率?

評鑑這段 console kernel code:

        $schedule->command('queue:restart')
            ->everyFiveMinutes()
            ->appendOutputTo(storage_path('logs/task.log'));

        $schedule->command('queue:work --daemon --timeout=900 --tries=254')
            ->everyMinute()
            ->withoutOverlapping()
            ->appendOutputTo(storage_path('logs/task.log'));

withoutOverlapping 的原理?

  • mutex 互斥鎖

https://divinglaravel.com/preventing-scheduled-jobs-overlapping


source code tracing

開始點:

https://github.com/laravel/framework/blob/5.4/src/Illuminate/Queue/Console/WorkCommand.php

src/Illuminate/Queue/Console/WorkCommand.php 定義了 queue:work 指令

此指令會執行 runWorker 跑worker. worker 會根據對應的 driver 從 queue 中取出任務. 接著根據參數執行 runNextJob 或是 daemon

        return $this->worker->{$this->option('once') ? 'runNextJob' : 'daemon'}(
            $connection, $queue, $this->gatherWorkerOptions()
        );

Worker

https://github.com/laravel/framework/blob/5.4/src/Illuminate/Queue/Worker.php

/src/Illuminate/Queue/Worker.php

首先使用 pcntl_signal php 函式監聽 Unix Signal 訊號. 此為 php 開發 daemon 程式常見作法.

接著 while (true) {} 跑無限迴圈來達成 daemon 效果. 再從對應的 driver 取出 queue 內任務

            $job = $this->getNextJob(
                $this->manager->connection($connectionName), $queue
            );

然後執行任務

            if ($job) {
                $this->runJob($job, $connectionName, $options);
            } else {
                $this->sleep($options->sleep);
            }
  分享   共 2,557 次點閱
共有 0 則留言
還沒有人留言。歡迎分享您的觀點、或是疑問。
您的留言
尤川豪
445 貼文  ·  275 留言

Devs.tw 是讓工程師寫筆記、網誌的平台。隨手紀錄、寫作,方便日後搜尋!

歡迎您一起加入寫作與分享的行列!

查看所有文章