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

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

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 6
Insua

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

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

然后在dotenv里配置QUEUE_NAME

1周前
yybawang

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

1周前

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

1周前

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

5天前
mostwin

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

5天前
yybawang

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

4天前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!