Laravel 5 即使有延迟,Laravel也会立即处理排队的作业

Laravel 5 即使有延迟,Laravel也会立即处理排队的作业,laravel-5,jobs,Laravel 5,Jobs,我目前正在开发关于私有服务器(例如服务器)的个人应用程序,由于查询服务器需要一些时间,我决定实现排队作业。但是,它们不能正常工作,即使它们被延迟,在调用时也会立即运行,从而在页面请求中造成巨大的延迟 以下是my HomeController的index(),它调用作业以30秒的延迟更新每台服务器: public function index() { $servers = Server::all(); foreach($servers as $server) {

我目前正在开发关于私有服务器(例如服务器)的个人应用程序,由于查询服务器需要一些时间,我决定实现排队作业。但是,它们不能正常工作,即使它们被延迟,在调用时也会立即运行,从而在页面请求中造成巨大的延迟

以下是my HomeController的index(),它调用作业以30秒的延迟更新每台服务器:

public function index()
{
    $servers = Server::all();

    foreach($servers as $server)
    {
        // Job Dispatch
        $job = (new UpdateServer($server->id))->delay(30);
        $this->dispatch($job);
    }
    return view('serverlist.index', compact('servers'));
}
更新服务器的作业类如下所示:

class UpdateServer extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    protected $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

    public function handle(){
        $server = Server::findOrFail($this->id);

        // Preparing the packet
        $test = new RAGBuffer();
        $test->addChar('255');
        $test->addChar('1');
        $test->addShort(1 | 8);

        // Finding the server
        $serverGame = new RAGServer($server->server_ip);

        // Get server information
        $status = $serverGame->sendPacket($test);

        $server->onlinePlayers = $status->getOnline();
        $server->peakPlayers = $status->getPeak();
        $server->maxPlayers = $status->getMax();

        if (!$server->save()) {
            // Error occurred
        }
    }
}
无论何时运行HomeController的index(),页面请求都会有很大的延迟。我在Laravel的官方网页上阅读了教程,我试图找到答案,但什么也没找到

那么,我做错了什么?为什么作业没有延迟30秒,然后在我的服务器后台执行此操作


另外:handle()正在做它应该做的事情。它查询服务器,发送数据包,并用正确的信息更新我的数据库。

您必须设置要在项目根目录的
.env
文件中使用的队列驱动程序

默认情况下,队列驱动程序是
sync
,它与您描述的完全一样,立即执行队列

您可以选择一些不同的队列驱动程序,例如beanstalked或redis(这是我的选择)。laracasts.com上有一个关于设置豆茎队列的链接

要查看Laravel中所有可用的队列驱动程序选项,请查看

下面是一个.env示例

APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomString

DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync      // <-- Put the desired driver here

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomString
DB_HOST=localhost
数据库=宅地
DB_USERNAME=宅地
DB_PASSWORD=secret
缓存驱动程序=文件
会话驱动程序=文件

QUEUE_DRIVER=sync/要进行本地测试,可以将驱动程序设置为

QUEUE_DRIVER=database
然后运行php artisan队列:table

然后php artisan迁移,这样你就可以将队列保存到数据库中,这样你就可以直观地看到发生了什么


要运行队列,只需运行php artisan queue:listen。。。并让它像您使用artisan serve一样运行。对于已经对以前的答案进行了更改但仍然不起作用的人,请检查队列文件的默认值,如下所示:
dd(Config::get('queue.default'))

对我来说,直到刷新配置缓存,它才改变:

php artisan config:clear
确保

'default' => env('QUEUE_DRIVER', 'database'), 
<env name="QUEUE_DRIVER" value="X"/>
在config/queue.php文件中


在.env文件中,确保使用了数据库驱动程序。

如果通过phpunit对队列服务运行测试,请确保

'default' => env('QUEUE_DRIVER', 'database'), 
<env name="QUEUE_DRIVER" value="X"/>


在phpunit.xml中,不会覆盖所需的队列驱动程序。

如果您运行的是
php artisan serve
,请重新启动此程序,然后再次运行
php artisan serve
。几个小时后,我一直想知道这是什么,这对我来说很有效。
:)

在我意识到Laravel 5.7在.env文件中将QUEUE\u驱动程序重命名为QUEUE\u连接之前,这让我疯狂了好长时间

即使您已正确配置了所有内容,这仍然可能发生。我们在Laravel 5.4中遇到了这个问题,在那里我们创建了很多作业,有些延迟了,并通过
queue:bulk($jobs)
将它们添加到队列中。此调用和
Queue::push($job)
完全忽略
延迟
,并立即处理作业


如果您希望按照配置将作业放入队列,则必须调用
dispatch($job)

这是因为延迟函数取未来的绝对日期

UpdateServer::dispatch($server->id)->delay(now()->addSeconds(30))

在我的例子中,我必须实现
ShouldQueue
并使用
Queueable
特性:

class CustomNotification extends Notification implements ShouldQueue{
    use Queueable;
...

谢谢你的回答,我想我会尝试beanstalked队列,所以,据我所知,它就像一个后台进程,对吗?它不会影响页面的加载时间或其他任何东西?不应该有任何影响(除了带宽,如果你关机,或者用脚本上传一些东西,但这不应该是一个问题)。Beanstalked是一个不错的选择,如果你关注视频,它会在几分钟内设置好。太糟糕了,我没有laracasts的帐户,因为它是必需的,我将尝试遵循其他教程,将标记你的问题为接受,一旦我得到这个工作,谢谢你的时间!这是另一个伟大的职位,帮助我得到设置。它提供了一个逐步配置的过程。我在使用
dispatch()
时遇到问题。当我切换到
\Queue::later(delay,job)
时,事情开始起作用了。对于本地开发,重新启动artisan服务器应该可以做到这一点(我经常忘记这一点),必须运行
队列:listen
命令,队列才能工作!谢谢你哦,天哪。非常感谢。我也是这样。