如何在 laravel 8 中动态设置速率限制器

Posted

技术标签:

【中文标题】如何在 laravel 8 中动态设置速率限制器【英文标题】:How to set the rate limiter dynamically in larvel 8 【发布时间】:2022-01-07 00:03:33 【问题描述】:

我需要根据存储在数据库表中的参数组合在 laravel 8 中动态设置速率限制器

S.No Key Param 1 Param 2 Param 3 Rate limit
1 adx param_1_a param_2_d param_3_x 20
2 buz param_1_b param_2_u param_3_z 30
3 cfy param_1_c param_2_f param_3_y 40

和速率限制器代码如下

protected function configureRateLimiting()

   RateLimiter::for('api', function (Request $request) 
      return [
        Limit::perMinute(rateLimit)->by(RateLimitKey)->response(function () 
        ...
        ),
        Limit::perMinute(rateLimit1)->by(RateLimitKey1)->response(function () 
        ...
        ),
      ];
   );

我需要在上面代码返回的数组中加入限速器

RateLimit 值将是数据库表中“速率限制”列的值

RateLimitKey 将结合列 Key、Param 1、Param 2、Param 3 的值(例如,key_param1_param2_param_3)

需要使用从数据库表中检索到的数据动态添加限速器

我不确定如何继续在 laravel 8 中添加速率限制器

【问题讨论】:

key在数据库中代表什么? 是请求中存在的参数 【参考方案1】:

您在上下文中有请求,所以从这里只是从DB 中获取数据。我假设它们是查询参数。请记住,这可以为 null,并且需要有一个后备。

DB::table('rate_limiting_table')
    ->where('key', $request->query('key'))
    ->where('param_1', $request->query('param_1'))
    ->where('param_2', $request->query('param_2'))
    ->where('param_3', $request->query('param_3'))
    ->first();

由于这将在每个 HTTP 请求上执行,我建议缓存它。

$cacheKey = $request->query('key') . $request->query('param_1') . $request->query('param_2') . $request->query('param_3');
cache()->remember($cacheKey, 14400, function ()  // cached for 4 hours
    return ... // your query
);

将所有这些逻辑放在一起,它可能看起来像这样。有一些小的干净代码改进。

const DEFAULT_RATE_LIMITING = 60;

protected function configureRateLimiting()

    RateLimiter::for('global', function (Request $request) 
        $rateLimiting = $this->getCacheRateLimiting();

        return $rateLimiting ? $rateLimiting->rate_limit : static::DEFAULT_RATE_LIMITING;
    );


private function getRateLimitingDatabase(): ?object 

    DB::table('rate_limiting_table')
        ->where('key', $request->query('key'))
        ->where('param_1', $request->query('param_1'))
        ->where('param_2', $request->query('param_2'))
        ->where('param_3', $request->query('param_3'))
        ->first();


private function getCacheRateLimiting(): ?object 

    // cached for 4 hours
    return cache()->remember($this->getRateLimitingCacheKey(), 14400, function () 
        return  $this->getRateLimitingDatabase();
    );


private function getRateLimitingCacheKey(): string

    return $request->query('key')
        . $request->query('param_1')
        . $request->query('param_2')
        . $request->query('param_3');

【讨论】:

实际上我已经通过将整个表存储在redis中来设置速率限制并使用redisearch添加了速率限制器。 我担心如果多个用户同时发送包含多个组合的请求,Ratelimiter 会起作用吗? @mrhn 但这真的不是你问的问题吗? "需要使用从数据库表中检索到的数据动态添加限速器"

以上是关于如何在 laravel 8 中动态设置速率限制器的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 中禁用速率限制器?

如何设置每天的laravel限速器?

如何用 Java 来构建一个简单的速率限制器?

如何防止 Geopy 出现此速率限制器错误?

Angular - http 拦截器 - http 速率限制器 - 滑动窗口

java 359.记录器速率限制器(#)。java