Класс RateLimiter
Класс RateLimiter из компонента Cache
позволяет ограничивать частоту выполнения
действий. Он создаётся через фабрику
RateLimiterFactory или через метод
create. Первым параметром в конфигурации
передаётся политика ограничения (например,
fixed_window или token_bucket),
вторым - лимит, третьим - интервал.
Метод consume расходует токены и
возвращает объект RateLimit с результатом.
Синтаксис
<?php
use Symfony\Component\RateLimiter\RateLimiterFactory;
$factory = new RateLimiterFactory($config, $storage);
$limiter = $factory->create($key);
$limit = $limiter->consume($tokens);
?>
Пример
Давайте создадим лимитер и израсходуем один токен:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;
class ArticleController extends AbstractController
{
public function index(): Response
{
$factory = new RateLimiterFactory([
'id' => 'article',
'policy' => 'fixed_window',
'limit' => 5,
'interval' => '1 minute',
], new InMemoryStorage());
$limiter = $factory->create('user');
$limit = $limiter->consume(1);
return new Response((string) $limit->getRemainingTokens());
}
}
?>
Результат выполнения кода:
"4"
Пример
Давайте проверим, принят ли запрос, и выведем время ожидания:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;
class ArticleController extends AbstractController
{
public function index(): Response
{
$factory = new RateLimiterFactory([
'id' => 'article',
'policy' => 'fixed_window',
'limit' => 2,
'interval' => '1 minute',
], new InMemoryStorage());
$limiter = $factory->create('user');
$limiter->consume(2);
$limit = $limiter->consume(1);
if (!$limit->isAccepted()) {
return new Response('retry after ' . $limit->getRetryAfter()->getTimestamp());
}
return new Response('accepted');
}
}
?>
Результат выполнения кода:
"retry after 1700000000"
Пример
Давайте сбросим состояние лимитера:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;
class ArticleController extends AbstractController
{
public function index(): Response
{
$factory = new RateLimiterFactory([
'id' => 'article',
'policy' => 'fixed_window',
'limit' => 1,
'interval' => '1 minute',
], new InMemoryStorage());
$limiter = $factory->create('user');
$limiter->consume(1);
$limiter->reset();
$limit = $limiter->consume(1);
return new Response((string) $limit->getRemainingTokens());
}
}
?>
Результат выполнения кода:
"0"
Смотрите также
-
класс
RateLimiter,
который управляет ограничением частоты запросов -
метод
consume,
который расходует токены лимитера -
метод
reset,
который сбрасывает состояние лимитера -
класс
RateLimit,
который хранит результат проверки лимита