多個 Laravel 應用 queue 佇列執行時會互串的問題

yybawang發表於2018-11-08

日常開發中會有多個 Laravel 專案同時進行,分發 Job queue 的時候預設並沒有做專案區分,只要分發的 onQueue("name") name 相同就會一起監聽執行。

生產環境還是很要注意的。

我用的解決小方法

1、寫一個公共方法,我寫在 app/Libriries/helper.php ,可以寫在你任何想放的地方

 /**
 * 多個 laravel 專案,如果 --queue 相同會互串
 * 這裡統一加個當前專案名的字首來區分
 * @param $name
 * @return string
 */
function queue_name($name){
    $name_trans = [];
    foreach(explode(',',$name) as $k => $v){
        $name_trans[] = str_slug(config('app.name') . ' ' . $v, '_');
    }
    return implode(',',$name_trans);
}

2、修改每個 Job 的 $queue 新增 queue_name()

namespace App\Jobs;
// 省略...
class ApiBehavior implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct()
    {
        // 新增這一行
        $this->queue = queue_name('你的佇列名');
    }
}

3、分發佇列

// 分發佇列時,照常分發即可
ApiBehavior::dispatch()
// 或者這種分發時指定,可以省略第二步。
ApiBehavior::dispatch()->onQueue(quque_name('你的佇列名'))

4、新建監聽佇列命令,包裝一層 quque:work,以使用自定義佇列名

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class QueueWorkListen extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'queue:work-listen
                            {connection? : The name of the queue connection to work}
                            {--queue= : The names of the queues to work}
                            {--daemon : Run the worker in daemon mode (Deprecated)}
                            {--once : Only process the next job on the queue}
                            {--delay=0 : The number of seconds to delay failed jobs}
                            {--force : Force the worker to run even in maintenance mode}
                            {--memory=128 : The memory limit in megabytes}
                            {--sleep=3 : Number of seconds to sleep when no job is available}
                            {--timeout=60 : The number of seconds a child process can run}
                            {--tries=0 : Number of times to attempt a job before logging it failed}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Start processing jobs on the queue as a daemon';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->call('queue:work',[
            'connection'=> $this->argument('connection'),
            '--queue'   => queue_name($this->option('queue') ?: 'default'),
            '--daemon'  => $this->option('daemon'),
            '--once'    => $this->option('once'),
            '--delay'   => $this->option('delay'),
            '--force'   => $this->option('force'),
            '--memory'  => $this->option('memory'),
            '--sleep'   => $this->option('sleep'),
            '--timeout' => $this->option('timeout'),
            '--tries'   => $this->option('tries'),
        ]);
    }
}

5、使用自定義命令監聽佇列,其他引數與 queue:work 一樣使用

php /var/www/ebank/artisan queue:work-listen --queue=email --sleep=3
// or 多個
php /var/www/ebank/artisan queue:work-listen --queue=email,test,test2,test3 --sleep=3

寫在最後

推薦使用 laradock 搭建開發/測試/生產環境,再也不用為windows/linux 環境不一樣煩惱了

相關文章