mik*_*oid 4 php jobs asynchronous laravel
我需要一种异步运行某些任务的方法,因为每个任务之间的执行时间不同,我想使用Laravel Jobs和数据库作为驱动程序以异步方式运行.
我创建了使用命令行测试作业:php artisan make:job TestOne php artisan make:job TestTwo
TestOne.php
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class TestOne extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
sleep(5);
foreach (range(1, 10) as $item)
\Log::info("TestOne: item #" . $item);
}
}
Run Code Online (Sandbox Code Playgroud)
TestTwo.php
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class TestTwo extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
foreach (range(1, 10) as $item)
\Log::info("TestTwo: item #" . $item);
}
}
Run Code Online (Sandbox Code Playgroud)
我只是在laravel的日志文件中记录一些消息,并且由于TestOne正在休眠5秒,TestTwo应该首先记录消息
HomeController.php
<?php
namespace App\Http\Controllers;
use Queue;
use App\Jobs\TestOne;
use App\Jobs\TestTwo;
class HomeController extends Controller
{
public function index()
{
$this->dispatch(new TestOne());
$this->dispatch(new TestTwo());
die("stop");
}
}
Run Code Online (Sandbox Code Playgroud)
但是TestTwo作业仍然等待,直到TestOne作业完成:
[2017-03-04 17:00:30] local.INFO: TestOne: item #1
[2017-03-04 17:00:30] local.INFO: TestOne: item #2
[2017-03-04 17:00:30] local.INFO: TestOne: item #3
[2017-03-04 17:00:30] local.INFO: TestOne: item #4
[2017-03-04 17:00:30] local.INFO: TestOne: item #5
[2017-03-04 17:00:30] local.INFO: TestOne: item #6
[2017-03-04 17:00:30] local.INFO: TestOne: item #7
[2017-03-04 17:00:30] local.INFO: TestOne: item #8
[2017-03-04 17:00:30] local.INFO: TestOne: item #9
[2017-03-04 17:00:30] local.INFO: TestOne: item #10
[2017-03-04 17:00:30] local.INFO: TestTwo: item #1
[2017-03-04 17:00:30] local.INFO: TestTwo: item #2
[2017-03-04 17:00:30] local.INFO: TestTwo: item #3
[2017-03-04 17:00:30] local.INFO: TestTwo: item #4
[2017-03-04 17:00:30] local.INFO: TestTwo: item #5
[2017-03-04 17:00:30] local.INFO: TestTwo: item #6
[2017-03-04 17:00:30] local.INFO: TestTwo: item #7
[2017-03-04 17:00:30] local.INFO: TestTwo: item #8
[2017-03-04 17:00:30] local.INFO: TestTwo: item #9
[2017-03-04 17:00:30] local.INFO: TestTwo: item #10
Run Code Online (Sandbox Code Playgroud)
我正在经营这些工作 php artisan queue:listen
我在这做错了什么?我真的需要这些任务以异步方式运行,就像JS AJAX请求一样.
我正在使用Laravel 5.2.我再次使用"database"作为队列驱动程序,是的,我已经迁移了jobs表.是不是可以使用数据库作为驱动程序?
要并行处理作业,你必须将它们分成不同的队列,正如@dparoli指出的那样.
这样,您不仅可以对它们进行分类,还可以优先考虑队列工作人员如何处理它们.
分派作业时,您将指定它所属的队列:
$this->dispatch((new TestOne())->onQueue('queue1'));
$this->dispatch((new TestTwo())->onQueue('queue2'));
Run Code Online (Sandbox Code Playgroud)
这样,您可以生成多个队列工作程序来单独处理作业:
php artisan queue:work --queue=queue1
php artisan queue:work --queue=queue2
Run Code Online (Sandbox Code Playgroud)
您还可以使用单个队列工作程序来优先处理队列的方式,这样您可以为某些作业提供比其他作业更高或更低的优先级:
php artisan queue:work --queue=queue2,queue1
Run Code Online (Sandbox Code Playgroud)
通过使用Supervisor等流程监视器,您甚至可以在文档中详细说明的多个流程中生成单个工作程序.
值得注意的是,除了给定的队列优先级之外,优先处理其队列的单个队列工作者仍将通过获取FIFO优先级来处理其作业.为了实现更好的并行性,您需要生成多个队列工作程序.
这适用于所有队列驱动程序.
异步意味着作业不会持有控制器方法的执行。例如,如果您添加sleep(5);到一和sleep(10);到二,die('stop');当您请求控制器时仍会立即发生。在同步执行中,需要 15 秒die才能到达。
FIFO 概念的队列类型(先进先出)。当你去超市时,如果你的物品比第二个人多很多(处理时间太长)也没关系,如果你是第一个排队的,第二个人就得等你完成。这就是队列的工作方式。
为了实现您想要的目标,我建议您进行一个简单的测试练习。
queue:listenphp artisan queue:work &从终端呼叫由于&会将进程发送到后台,您queue:work几乎可以在瞬间自由发出两次。这应该会带来您期望的行为。
这是我的输出
[03:01 PM]-[root@php7]-[/var/www/html/jobs]
php artisan queue:work &
[1] 2456
[03:02 PM]-[root@php7]-[/var/www/html/jobs]
php artisan queue:work &
[2] 2458
[03:02 PM]-[root@php7]-[/var/www/html/jobs]
[2017-03-04 18:02:33] Processed: App\Jobs\TaskTwo
[2017-03-04 18:02:37] Processed: App\Jobs\TaskOne
Run Code Online (Sandbox Code Playgroud)
我试图提出的观点是:
queue:listen 将一次运行一项工作,并在第一个完成后才开始下一个;queue:work将开始第一个作业并将其标记为保留(列reserved_at),以便下一个queue:work可以执行下一个未保留的作业。