我目前正在开发关于私人服务器(例如Minecraft服务器)的个人应用程序,并且由于查询服务器需要一些时间,我决定实施排队作业,但是,它们工作不正常,即使在调用时也会立即运行它们被延迟,导致页面请求的大量延迟。
这是我的HomeController的索引(),它调用作业以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 info
$status = $serverGame->sendPacket($test);
$server->onlinePlayers = $status->getOnline();
$server->peakPlayers = $status->getPeak();
$server->maxPlayers = $status->getMax();
if (!$server->save()) {
//error ocurred
}
}
}
每当HomeController的index()运行时,页面请求都会出现大量延迟,我按照Laravel官方网页上的教程,试图找到答案而没有任何答案。
那么,我做错了什么?为什么这个工作没有延迟30秒,然后在我的服务器后台执行此操作?先感谢您。
另外:handle()正在做它应该做的事情,它查询服务器,发送数据包并用正确的信息更新我的数据库。
您必须在项目的根目录的.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
对于已进行上述更改但仍无法正常工作的人员,请检查队列文件的默认值,如下所示:dd(Config::get('queue.default'))
对我来说,在刷新配置缓存之前它没有改变:
php artisan config:clear
在我意识到Laravel 5.7在.env文件中将QUEUE_DRIVER重命名为QUEUE_CONNECTION之前,这让我疯狂了很久
如果您在php artisan serve
上运行,请重新启动它并再次运行php artisan serve
。这对我有用,经过几个小时试图想知道它是什么。 :)
要在本地测试,您可以将驱动程序设置为
QUEUE_DRIVER=database
并运行php artisan queue:table然后php artisan migrate,这样你就可以将你的队列保存到数据库中,这样你就可以直观地了解发生了什么。
并运行你的队列简单运行php artisan队列:听..并让它像工匠服务一样运行
确保这件事
'default' => env('QUEUE_DRIVER', 'database'),
在config / queue.php和
QUEUE_DRIVER=database
在.env文件中,以确保使用数据库驱动程序
如果您通过phpunit对队列服务运行测试,请确保
<env name="QUEUE_DRIVER" value="X"/>
在phpunit.xml中不会覆盖您想要的队列驱动程序。
即使你已经正确配置了一切,这仍然可能发生。我们在Laravel 5.4中遇到了这个问题,我们创建了很多作业,一些延迟了,并通过Queue:bulk($jobs)
将它们添加到队列中。此调用以及Queue::push($job)
完全忽略了delay
并导致立即处理作业。
如果您希望在配置作业时将作业放入队列,则必须调用dispatch($job)
。