Laravel 可以在队列中放置后台任务吗?

大家好,这几天在做一个这样的 api:

输入 ID 后需要汇总输出关于它的各维度的数据(通过三方接口抓取)。但现在有个问题就是,由于数据量极大,所以接口一直无法返回数据直至超时。

我想到了用后台任务开多进程跑,但我不希望这些任务定时去跑,而是有任务就执行。况且每次跑的任务参数都不同(输入的 ID 不同)。

最后想到了队列,用户每提交一个查询请求,就把这个任务放入队列,然后每一个队列任务都相当于按照指定参数去跑后台任务。这个思路有木有问题呢?我尝试了一下貌似不可以。

我实现的代码如下:
Controller代码:

<?php

namespace App\Http\Controllers\Complex;

use App\Http\Controllers\APIController;
use App\Jobs\HandleUserComment;
use Illuminate\Http\Request;

class CommentController extends APIController
{
    public function getUserComment(Request $request)
    {
        HandleUserComment::dispatch($request->uid);
        return $this->success();
    }
}

Jobs代码:

<?php

namespace App\Jobs;

use App\Console\Boot;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class HandleUserComment implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $uid;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($uid)
    {
        $this->uid = $uid;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle(Comment $comment, PlaylistHandler $playlistHandler, UserHandler $userHandler)
    {
        //这里略去获取三方数据的逻辑代码
        //以下代码是希望启用200个子进程来执行这个后台任务
        $boot = new Boot();
        $boot->scryed($musicIds, [base_path() .'/artisan','netease:comment', $this->uid], 200);
    }
}

Commend 代码:

<?php

namespace App\Console\Commands;

use App\Console\Boot;
use App\Models\Handler\CommentHandler;
use App\Models\Music;
use App\Models\Comment as CommentModel;
use App\Services\Netease;

class CommentV2 extends Boot
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'netease:comment {uid} {--limit=} {--offset=} {--data=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'xxx';

    protected $uid;

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

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //这里是处理数据的逻辑,测试将数据写入数据库
    }
}

以上就是关键代码,但是开启了 php artisan queue:work 后,调用接口没有任何输出,数据库也没有任何数据写入。是不是后台任务不能通过这种方式调用呢?求解答~~

代码是写给人看的,顺便给机器运行一下。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 3

可以的,要配置下队列执行的超时时间限制,默认只有 60 秒

3年前 评论
luci (楼主) 3年前

可以调用,但是 worker 和 PHP-FPM 不是一个进程,HTTP 请求周期内无法确定任务被分发以后的具体处理时间。如果要用 Queue 的话那么,可以考虑再任务完成后给用户发送邮件通知,然后用户点击连接查看生成的数据。

3年前 评论
luci (楼主) 3年前

你应该想办法分而治之,尽量不要在一个job里处理太多事情

3年前 评论
luci (楼主) 3年前

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