You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 09:20:22