阻止第三方 API 崩溃:限流 Laravel 作业 🚦
Source: Dev.to

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:定义速率限制器
首先,在 AppServiceProvider 的 boot 方法中定义外部 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 的声誉,并确保即使需要数小时安全地滴灌数据,大规模的数据同步也能成功完成。