Laravel排队的工作立即处理,即使有延迟

时间:2015-06-27 17:32:22

标签: laravel-5 jobs

我目前正在开发关于私人服务器(例如Minecraft服务器)的个人应用程序,并且由于查询服务器需要一些时间,我决定实施排队作业,但是,它们无法正常工作,它们会立即运行即使它们被延迟也会调用,导致页面请求出现大量延迟。

这是我的HomeController的索引(),它调用作业以30秒的延迟更新每个服务器:

- (void)testCreatingUserRequest {
    // Initialize necessary objects
    RestManager *restManager = ...
    CreatingUserRequest *request = ...

    // Execute test
    XCTestExpectation *expectation = [self expectationWithDescription:@"Create User"];

    [restManager createUserWithRequest:request completionHandler:^(NSDictionary *JSONObject, NSError *error) {
        XCTAssertNotNil(JSONObject);
        XCTAssertNotNil([User userWithJSONObject:JSONObject]);
        XCTAssertNil(error);

        [expectation fulfill];
    }];

    [self waitForExpectationsWithTimeout:30 handler:^(NSError *error) {
        XCTAssertNil(error);
    }];
}

更新服务器的作业类如下:

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'));
}

每当HomeController的index()运行时,页面请求都会出现大量延迟,我按照Laravel官方网页上的教程,试图找到答案而不做任何事情。

那么,我做错了什么?为什么这个工作没有延迟30秒,然后在我的服务器后台执行此操作?提前谢谢。

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

10 个答案:

答案 0 :(得分:26)

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

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

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

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

这是一个.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

答案 1 :(得分:7)

对于已进行上述更改但仍无效的用户,请检查队列文件的默认值,如下所示:dd(Config::get('queue.default'))

对我来说,在刷新配置缓存之前它没有改变:

php artisan config:clear

答案 2 :(得分:6)

这使我疯狂了好多年,直到我意识到Laravel 5.7在.env文件中将QUEUE_DRIVER重命名为QUEUE_CONNECTION

答案 3 :(得分:5)

如果您在php artisan serve上运行,请重新启动并再次运行php artisan serve。这对我有用,经过几个小时试图想知道它是什么。 :)

答案 4 :(得分:2)

要在本地测试,您可以将驱动程序设置为

QUEUE_DRIVER=database 

并运行 php artisan queue:table 然后 php artisan migrate ,这样你就可以将你的队列保存到数据库中,这样你就可以看到发生了什么......

并运行你的队列简单运行 php artisan队列:监听 ..并让它像工匠服务一样运行

答案 5 :(得分:1)

确保

'default' => env('QUEUE_DRIVER', 'database'), 

在config / queue.php和

QUEUE_DRIVER=database 
<。>在.env文件中以确保使用数据库驱动程序

答案 6 :(得分:1)

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

<env name="QUEUE_DRIVER" value="X"/>
phpunit.xml中的

不会覆盖您想要的队列驱动程序。

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

这是因为延迟功能在将来需要一个绝对日期

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

答案 9 :(得分:0)

就我而言,我必须实现ShouldQueue并使用Queueable特质:

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