这是 Laravel 非常“城区化”的另一部分。
很多系统在同步请求里做太多事:
- 创建订单
- 发短信
- 发邮件
- 记审计日志
- 通知仓库
- 生成发票
- 推送到 CRM
结果就是前台工头一边接单,一边自己冲去后场干体力活。
Laravel 的思路更像成熟城区:
Event = 某件事发生了,广播出去
Queue = 这件慢活别堵前台,送到后场传送带最关键的一刀是:
事件不是任务,任务也不是事件。
OrderCreated
= “订单已创建”这个事实发生了
SendInvoiceJob
= “请去生成发票”这个待执行动作一个简单事件:
use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class OrderCreated
{
use Dispatchable, SerializesModels;
public function __construct(
public Order $order,
) {}
}一个监听器可以选择进入队列:
<?php
namespace App\Listeners;
use App\Events\OrderCreated;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Queueable;
use Illuminate\Support\Facades\Log;
class PrepareWorkshopMaterials implements ShouldQueue
{
use InteractsWithQueue, Queueable;
public function handle(OrderCreated $event): void
{
Log::info('准备订单物料', [
'order_id' => $event->order->id,
'product' => $event->order->product,
'quantity' => $event->order->quantity,
]);
}
}关系图如下:
Controller / Service
|
v
Event::dispatch(new OrderCreated($order))
|
v
Listener
|
+--> 同步执行
|
+--> 或实现 ShouldQueue
|
v
Queue
|
v
Queue Worker这套模型特别像现实工坊:
前台先确认“订单已成立”
然后广播给后场
后场各工位再异步做自己的活这就是解耦。