阻止第三方 API 崩溃:限流 Laravel 作业 🚦

发布: (2026年5月4日 GMT+8 12:47)
4 分钟阅读
原文: Dev.to

Source: Dev.to

《停止崩溃第三方 API:对 Laravel 任务进行限流》封面图 🚦

API 速率限制灾难

在 Smart Tech Devs 的现代 B2B SaaS 开发中,您的应用程序很少是孤立运行的。您会不断与外部服务进行通信:通过 Stripe 进行计费、通过 Salesforce 同步 CRM,或通过 Resend 发送邮件活动。当您将 Laravel Queues 的极高并发能力与这些第三方 API 的严格速率限制相结合时,就会陷入架构陷阱。

如果您派发 5,000 条 “同步客户” 背景任务,Laravel Horizon 工作进程会尽可能快地执行它们,受限于 CPU 的处理能力。如果第三方 API 每分钟只允许 50 次请求,前 50 条任务会成功,而剩余的 4,950 条会立即因 HTTP 429: Too Many Requests 错误而崩溃。这会使失败任务表被大量填满,在 Sentry 中触发误报,并导致数据同步中断。

Source:

企业解决方案:Redis 作业中间件

为了构建可靠的后台处理,我们必须让队列工作者遵守外部限制。我们通过在排队作业上直接使用 速率限制中间件(Rate Limiting Middleware)并借助 Redis 来实现。

当 API 达到限制时,作业不会直接崩溃,而是由中间件安全拦截,暂停作业并将其重新放回队列,待速率限制重置后再尝试。

步骤 1:定义速率限制器

首先,在 AppServiceProviderboot 方法中定义外部 API 的严格速率限制。

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Cache\RateLimiting\Limit;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        // 定义严格限制:每分钟最多 50 次请求
        RateLimiter::for('salesforce-api', function ($job) {
            return Limit::perMinute(50);
        });
    }
}

步骤 2:将中间件应用到作业

在作业类中使用 middleware() 方法绑定特定的速率限制器,并配置在被限流时作业应等待多长时间后重试。

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\Queue\Middleware\RateLimited;

class SyncCustomerToSalesforce implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tenant;

    // 允许作业最多重试 12 小时
    public $retryUntil;

    public function __construct($tenant)
    {
        $this->tenant = $tenant;
        $this->retryUntil = now()->addHours(12);
    }

    /**
     * 获取作业应通过的中间件。
     */
    public function middleware(): array
    {
        // 1. 应用我们在提供者中定义的 Redis 限流器
        // 2. 若被限流,使用 60 秒延迟将作业重新放回队列
        return [
            (new RateLimited('salesforce-api'))->dontRelease()->releaseAfterMinutes(1)
        ];
    }

    /**
     * 执行作业(安全防止 429 错误!)
     */
    public function handle(): void
    {
        // 在此执行外部 API 的 HTTP 请求...
        // 我们保证全局每分钟仅执行 50 次。
    }
}

架构 ROI

通过实现基于 Redis 的作业限流,您可以将混乱的 API 集成转变为节奏恰当、具弹性的数据管道。您可以消除日志中 429 错误的噪声,保护供应商 API 的声誉,并确保即使需要数小时安全地滴灌数据,大规模的数据同步也能成功完成。

0 浏览
Back to Blog

相关文章

阅读更多 »

在 Laravel 中集成 SB Admin 2

Laravel 11 要求 bash php -v >= 8.2 composer -v node -v >= v14.16 npm -v 在你的 web 服务器上启动 Apache 与 MySQL。 安装 Laravel 11 bash composer create…