【发布时间】:2016-06-09 19:29:09
【问题描述】:
编辑 2:
以下是我们正在经历的步骤:
- 计划正在运行(为每个公司创建
CollectHistoricalData工作) -
CollectHistoricalData应该被推送到队列(jobs表) -
CollectHistoricalData有一个函数ApiDaemon::GetCompanyWithQuery($company, $query),它从一个单独的类运行,该类也被其他几个地方引用。 -
GetCompanyWithQuery收集数据并将其插入数据库。
它一直运行良好,但挂断不是将作业插入作业表,它只是同步运行,一个接一个。
编辑 1:
.env 文件设置为使用database QUEUE_DRIVER,我什至尝试在config/queue.php 文件中对其进行硬编码。
我们在一个项目中使用 Laravel 5.2。在这个项目中,我们需要每小时 cURL 一个 url 并将数据保存到数据库中。我们一开始使用的是 Cron Jobs,基本上在一分钟内触发了数千个 cURL,这会使 PHP 因负载而崩溃。
我们决定转移到 Laravel 的作业和队列,但没有成功。我们正在为我们的作业使用数据库驱动程序,并尝试了许多不同的方法将作业放入数据库中,因此我们拥有的守护进程可以处理它们。
这是我们现在的代码,我们正在使用 Kernel.php $schedule 来启动这件事,因此我们不会在一小时内尝试发生数百个请求,这会导致数万个 cURL。
Kernel.php 时间表:
$schedule
->call(function () {
$items = DB::select('{selecting certain things to run}');
foreach ($items as $q) {
$this->dispatch(new CollectHistoricalData(Company::find($q->company_id), ApiQuery::find($q->query_id)));
}
})
->hourly()
->name('Historical Pulls')
->withoutOverlapping()
->before(function() {
$this->startTime = Carbon::now();
})
->after(function () {
mail({mail us a report afterward});
});
当它运行时,它会坐在那里一个一个地运行它们,而不是将它们推送到创建的 Jobs 表中。
收集历史数据.php:
<?php
namespace App\Jobs;
use App\Helpers\Daemons\ApiDaemon;
use App\Jobs\Job;
use App\Models\Company;
use App\Models\ApiQuery;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class CollectHistoricalData extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $company, $query;
/**
* CollectHistoricalData constructor.
* @param Company $company
* @param ApiQuery $query
*/
public function __construct(Company $company, ApiQuery $query)
{
$this->company = $company;
$this->query = $query;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
mail({let us know what started and when});
QueryDaemon::GetCompanyWithQuery($this->company, $this->query);
}
public function failed()
{
mail({mail us letting us know it failed});
}
}
这项工作是引用另一个类,其中包含函数(因为该代码本身就是一个沉重的野兽),加上其中大约有 20 个,因此引用该类而不是重新创建所有 20 个类是最简单的进入乔布斯。
TL;DR
我们有一个计划,它应该将引用另一个类中的函数的作业推送到作业表中,而是一个接一个地缓慢运行它们。这是什么原因造成的?
【问题讨论】:
-
您的
.env文件中指定的QUEUE_DRIVER是什么? -
QUEUE_DRIVER在.env文件中设置为database,而且我什至尝试在config/queue.php文件中进行硬编码。 -
Company::find($q->company_id)和ApiQuery::find($q->query_id)是否在做应该排队的工作?这会立即在您的内核中被调用,并且只是将结果传递给作业类。 -
是的,每次都会找到公司和apiQuery,我看到他们处理并将api信息插入数据库,但它一次处理一个而不是将它们推入队列.
-
听起来您需要将
Company和ApiQuery代码移动到排队作业的handle()方法中,这是排队后运行的唯一方法。
标签: php mysql laravel curl laravel-5.2