多个 Laravel 应用 queue 队列执行时会互串的问题

日常开发中会有多个 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 环境不一样烦恼了

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 2年前 自动加精
yybawang
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 6

不需要这么麻烦,我用redis做队列
queue.php里配置一下就行了

 'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue'  => env('QUEUE_NAME', 'queue'),
            'retry_after' => 90,
        ],

然后在dotenv里配置QUEUE_NAME

5年前 评论
萧风 4年前
Insua (作者) 4年前
yybawang

@Insua --queue=多个 这里配置不了

5年前 评论

@yybawang 可以试一下,在.env文件中配置的时候,值使用"括起来

5年前 评论

不是同一个项目,不是同一个目录,REDIS的话 指定一下数据库的ID,用不到这么复杂啊

5年前 评论

redis 为什么配置同一个库呢?

5年前 评论
yybawang

@mostwin 没毛病,没发现这个配置...是我走弯了

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!