使用Laravel计数对外部API的API请求

5jvtdoz2  于 2022-11-18  发布在  其他
关注(0)|答案(3)|浏览(190)

我一直在尝试解决一个外部服务有速率限制的问题。我的Laravel应用将通过作业处理常规请求。用户也可以与外部服务交互。这意味着作业请求+用户请求很容易超过服务的速率限制,并导致X分钟超时(禁止)。为了防止这种情况,Laravel应用程序必须知道最近X分钟/秒的请求数量,以允许在不超过API速率的情况下执行某个方法。有人遇到过同样的问题吗?您是如何解决的?

bakd9h0s

bakd9h0s1#

一个解决方案可能是使用一个表来存储每个url(或服务提供商)的请求数以及重置时间。当你想进行查询时,你可以参考静态Eloquent模型来检索对该url的请求数,并检查你是否没有达到最大值。此外,你可以使用一个服务或任务来重置这个特定表上的计时器,当达到重置时间时。
对你有帮助吗?

xvw2m8pv

xvw2m8pv2#

如果您只想计算API请求的结果,您可以设置事件监听器,它们填充数据库中的requests表之类的内容。
因此,在EventServiceProvider中注册 * 事件 * 和 * 监听器 *:

protected $listen = [
    'App\Events\RequestSent' => [
        'App\Listeners\IncrementCounterIntoRequestsDBTable',
    ],
];

然后:php artisan event:generate
请参阅文档
在这种情况下,每个请求都会调度一个event,该event会递增requests表中的计数器。


但如果要解决第三方API速率限制的问题:

优化并创建类似缓存的内容:如果您不需要“严格”实时,您可以:

  • 通过命令或其他作业,每XX分钟调度一次API请求
  • 将最新数据存储到***内部***DB中
  • 那么您可以将此数据提供给用户请求。

通过这种方式,您可以根据速率限制,每XX分钟进行一次“预定义”更新。
例如,如果速率限制为1.500 req/天,则可以每分钟更新数据。

chhkpiq4

chhkpiq43#

对于这种类型的场景,您可以创建一个定制的中间件来处理不同类型的请求。
1.通过命令=〉php artisan make:middleware requestCountMiddleware创建中间件
1.对于新日志表,您可以创建RequestLog::class的迁移和模型,其中列为id (autoincrement) , count(big integer), timestamps()
1.然后,在App/Http/Middleware/requestCountMiddleware.php中创建逻辑,用于根据RequestLog表中的日期存储或更新每个请求的条目。

4.根据您的要求提供示例逻辑=〉

public function handle($request, Closure $next)
{
    $checkRequest = App\Models\RequestLog::whereDate('created_at', Carbon::now()->format('Y-m-d'))->first();
    if(!$checkRequest){
        $checkRequest = new App\Models\RequestLog();
    }
    $checkRequest->count += 1;
    $checkRequest->save();
    return $next($request);
}

1.您还可以从作业方法执行相同的逻辑来添加或更新请求计数。

6.因此,无论何时需要按日期计数,您都可以使用此类型查询从该表中获取=〉****$date = Any Date您希望从表中获取的数据(2022-09-27)

App\Models\RequestLog::whereDate('created_at', $date)->value('count');

7.在用户请求路由中使用该中间件=〉

Route::get('/details', function () {
    //
})->middleware('requestCountMiddleware');

此外,如果你想处理多个请求,如超过60或120请求每分钟,你也可以设置RateLimiter处理最大数量的请求接受每个IP或每个用户在Laravel应用程序。

相关问题