我一直在尝试解决一个外部服务有速率限制的问题。我的Laravel应用将通过作业处理常规请求。用户也可以与外部服务交互。这意味着作业请求+用户请求很容易超过服务的速率限制,并导致X分钟超时(禁止)。为了防止这种情况,Laravel应用程序必须知道最近X分钟/秒的请求数量,以允许在不超过API速率的情况下执行某个方法。有人遇到过同样的问题吗?您是如何解决的?
bakd9h0s1#
一个解决方案可能是使用一个表来存储每个url(或服务提供商)的请求数以及重置时间。当你想进行查询时,你可以参考静态Eloquent模型来检索对该url的请求数,并检查你是否没有达到最大值。此外,你可以使用一个服务或任务来重置这个特定表上的计时器,当达到重置时间时。对你有帮助吗?
xvw2m8pv2#
如果您只想计算API请求的结果,您可以设置事件和监听器,它们填充数据库中的requests表之类的内容。因此,在EventServiceProvider中注册 * 事件 * 和 * 监听器 *:
requests
EventServiceProvider
protected $listen = [ 'App\Events\RequestSent' => [ 'App\Listeners\IncrementCounterIntoRequestsDBTable', ], ];
然后:php artisan event:generate请参阅文档在这种情况下,每个请求都会调度一个event,该event会递增requests表中的计数器。
php artisan event:generate
event
但如果要解决第三方API速率限制的问题:
优化并创建类似缓存的内容:如果您不需要“严格”实时,您可以:
通过这种方式,您可以根据速率限制,每XX分钟进行一次“预定义”更新。例如,如果速率限制为1.500 req/天,则可以每分钟更新数据。
chhkpiq43#
对于这种类型的场景,您可以创建一个定制的中间件来处理不同类型的请求。1.通过命令=〉php artisan make:middleware requestCountMiddleware创建中间件1.对于新日志表,您可以创建RequestLog::class的迁移和模型,其中列为id (autoincrement) , count(big integer), timestamps()。1.然后,在App/Http/Middleware/requestCountMiddleware.php中创建逻辑,用于根据RequestLog表中的日期存储或更新每个请求的条目。
php artisan make:middleware requestCountMiddleware
RequestLog::class
id (autoincrement) , count(big integer), timestamps()
App/Http/Middleware/requestCountMiddleware.php
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应用程序。
3条答案
按热度按时间bakd9h0s1#
一个解决方案可能是使用一个表来存储每个url(或服务提供商)的请求数以及重置时间。当你想进行查询时,你可以参考静态Eloquent模型来检索对该url的请求数,并检查你是否没有达到最大值。此外,你可以使用一个服务或任务来重置这个特定表上的计时器,当达到重置时间时。
对你有帮助吗?
xvw2m8pv2#
如果您只想计算API请求的结果,您可以设置事件和监听器,它们填充数据库中的
requests
表之类的内容。因此,在
EventServiceProvider
中注册 * 事件 * 和 * 监听器 *:然后:
php artisan event:generate
请参阅文档
在这种情况下,每个请求都会调度一个
event
,该event
会递增requests
表中的计数器。但如果要解决第三方API速率限制的问题:
优化并创建类似缓存的内容:如果您不需要“严格”实时,您可以:
通过这种方式,您可以根据速率限制,每XX分钟进行一次“预定义”更新。
例如,如果速率限制为1.500 req/天,则可以每分钟更新数据。
chhkpiq43#
对于这种类型的场景,您可以创建一个定制的中间件来处理不同类型的请求。
1.通过命令=〉
php artisan make:middleware requestCountMiddleware
创建中间件1.对于新日志表,您可以创建
RequestLog::class
的迁移和模型,其中列为id (autoincrement) , count(big integer), timestamps()
。1.然后,在
App/Http/Middleware/requestCountMiddleware.php
中创建逻辑,用于根据RequestLog表中的日期存储或更新每个请求的条目。4.根据您的要求提供示例逻辑=〉
1.您还可以从作业方法执行相同的逻辑来添加或更新请求计数。
6.因此,无论何时需要按日期计数,您都可以使用此类型查询从该表中获取=〉****$date = Any Date您希望从表中获取的数据(2022-09-27)
App\Models\RequestLog::whereDate('created_at', $date)->value('count');
7.在用户请求路由中使用该中间件=〉
此外,如果你想处理多个请求,如超过60或120请求每分钟,你也可以设置RateLimiter处理最大数量的请求接受每个IP或每个用户在Laravel应用程序。