如何在Laravel中暂停第三方API故障时的队列任务并恢复执行?
Laravel队列实现第三方服务故障时暂停消费、恢复后执行的方案
针对你的场景——下单接口异步调用第三方API,第三方宕机时暂停队列消费,恢复后再处理任务,而非依赖默认重试机制——可以通过服务健康监控+队列启停控制的方式实现,具体步骤如下:
1. 实现第三方服务健康检测
先写一个工具类,用来检测第三方API的可用性:
<?php namespace App\Services; use Illuminate\Support\Facades\Http; class ThirdPartyHealthChecker { public function isAvailable(): bool { try { // 用HEAD请求更高效,也可根据实际需求用GET/POST $response = Http::timeout(3)->head('third-party.com/api/get-data'); return $response->successful(); } catch (\Exception $e) { // 捕获超时、连接失败等异常,判定服务不可用 return false; } } }
2. 创建队列任务类
任务类专注于调用第三方API,无需处理重试逻辑:
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Http; class CallThirdPartyApi implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $orderData; public function __construct(array $orderData) { $this->orderData = $orderData; } public function handle() { // 直接调用第三方API,队列启停逻辑由监控脚本控制 Http::post('third-party.com/api/get-data', $this->orderData); } }
3. 编写队列监控命令
创建一个Artisan命令,定时检查第三方服务状态,自动启停指定队列:
<?php namespace App\Console\Commands; use App\Services\ThirdPartyHealthChecker; use Illuminate\Console\Command; use Illuminate\Support\Facades\Process; class MonitorThirdPartyQueue extends Command { protected $signature = 'queue:monitor-third-party'; protected $description = 'Monitor third-party service and control queue consumption'; public function handle(ThirdPartyHealthChecker $healthChecker) { $queueName = 'third-party'; // 给第三方任务单独分配队列,不影响其他业务 $serviceAvailable = $healthChecker->isAvailable(); // 检查队列进程是否在运行 $queueRunning = !empty(Process::run("ps aux | grep 'queue:work {$queueName}' | grep -v grep")->output()); if (!$serviceAvailable && $queueRunning) { // 服务宕机,停止队列消费 Process::run("php artisan queue:stop {$queueName}"); $this->warn("Third-party service unavailable. Stopped queue: {$queueName}"); } elseif ($serviceAvailable && !$queueRunning) { // 服务恢复,启动队列消费(用nohup后台运行,也可结合supervisor管理) Process::run("nohup php artisan queue:work {$queueName} --daemon > /dev/null 2>&1 &"); $this->info("Third-party service restored. Started queue: {$queueName}"); } else { $this->info("Status unchanged - Queue {$queueName} state maintained"); } } }
4. 配置定时监控
在app/Console/Kernel.php中添加调度规则,让监控命令每分钟执行一次:
protected function schedule(Schedule $schedule) { $schedule->command('queue:monitor-third-party')->everyMinute(); }
5. 下单接口分发任务
在订单接口控制器中,保存订单后将任务分发到指定队列:
public function placeOrder(Request $request) { // 验证并保存订单数据到数据库 $order = Order::create($request->validate([ // 你的订单字段验证规则 ])); // 分发任务到第三方专属队列 CallThirdPartyApi::dispatch($order->toArray())->onQueue('third-party'); return response()->json([ 'status' => 'success', 'message' => '订单提交成功' ]); }
注意事项
- 队列隔离:务必给第三方任务分配独立队列,避免影响其他业务的队列任务。
- 进程管理:生产环境建议用
supervisor替代nohup管理队列进程,稳定性更强。 - 健康检查优化:可以根据第三方API的特点调整检查方式(比如调用专门的健康检查接口),减少对业务接口的干扰。
- 日志记录:可以在监控命令中添加日志记录,方便排查服务状态变化的时间点。
内容的提问来源于stack exchange,提问作者Hasan Hafiz Pasha
相关产品推荐
相关产品推荐

