Rate Limiting в PHP: Ограничение частоты запросов для защиты сайта

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Rate Limiting в PHP: Полное руководство по защите от перегрузок

Rate Limiting (ограничение частоты запросов) — это критически важный механизм защиты веб-приложений. Он предотвращает злоупотребление ресурсами сервера, защищает от DDoS-атак, брутфорса паролей и спама. В PHP существует несколько эффективных подходов и библиотек для реализации rate limiting. В этой статье мы рассмотрим лучшие инструменты, принципы работы и практические примеры.

Что такое Rate Limiting и зачем он нужен?

Rate Limiting устанавливает максимальное количество запросов, которое клиент (IP-адрес, пользователь или API-ключ) может выполнить за определённый промежуток времени. Основные цели:

  • Защита от DDoS — предотвращение перегрузки сервера ботами
  • Предотвращение брутфорса — ограничение попыток входа в систему
  • Справедливое распределение ресурсов — равный доступ для всех пользователей
  • Экономия серверных ресурсов — снижение нагрузки на базу данных и процессор

Популярные алгоритмы Rate Limiting

Перед выбором библиотеки важно понимать основные алгоритмы:

  • Token Bucket (Токен-ведро) — накапливает токены с определённой скоростью, позволяет кратковременные всплески трафика
  • Leaky Bucket (Дырявое ведро) — сглаживает трафик, обрабатывая запросы с постоянной скоростью
  • Fixed Window (Фиксированное окно) — считает запросы за фиксированный интервал времени
  • Sliding Window (Скользящее окно) — более точный вариант, учитывающий запросы в скользящем временном окне

Лучшие библиотеки для Rate Limiting в PHP

1. Symfony Rate Limiter

Официальный компонент Symfony, который можно использовать независимо от фреймворка. Поддерживает Redis, APCu и файловое хранилище.

composer require symfony/rate-limiter

Пример использования:

<?php
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;

$factory = new RateLimiterFactory([
    'id' => 'login',
    'policy' => 'token_bucket',
    'limit' => 10,
    'rate' => ['interval' => '1 minute'],
], new InMemoryStorage());

$limiter = $factory->create('user_123');

if ($limiter->consume()->isAccepted()) {
    // Разрешить запрос
    echo "Доступ разрешен";
} else {
    // Отклонить запрос
    http_response_code(429);
    echo "Слишком много запросов";
}
?>

2. PHP RateLimiter (by bantu)

Легковесная библиотека для простых сценариев. Поддерживает Redis, Memcached и файлы.

composer require bantu/php-ratelimiter

Пример:

<?php
use bantu\RateLimiter\RateLimiterFactory;

$factory = new RateLimiterFactory();
$limiter = $factory->createRedisRateLimiter(
    new \Predis\Client(),
    'api_limit',
    100, // лимит запросов
    3600 // окно в секундах
);

if ($limiter->hit($_SERVER['REMOTE_ADDR'])) {
    echo "Запрос принят";
} else {
    http_response_code(429);
    echo "Лимит исчерпан";
}
?>

3. GrahamCampbell/Laravel RateLimiter

Если вы работаете с Laravel, это нативное решение. Встроено в фреймворк начиная с версии 8.

<?php
use Illuminate\Support\Facades\RateLimiter;

// Определение лимитера в AppServiceProvider
RateLimiter::for('api', function ($job) {
    return \Illuminate\Cache\RateLimiting\Limit::perMinute(60)->by($job->user->id ?: $job->ip());
});

// Использование в контроллере
public function store(Request $request)
{
    if (RateLimiter::tooManyAttempts('send-message:'.$request->ip(), 5)) {
        return response('Слишком много сообщений', 429);
    }
    RateLimiter::hit('send-message:'.$request->ip(), 60);
    // Обработка сообщения
}
?>

Реализация Rate Limiting с Redis (без библиотек)

Если вы предпочитаете минималистичные решения, можно реализовать rate limiting с помощью Redis INCR и EXPIRE:

<?php
$redis = new Redis();
$redis->connect('127.0.0                    

Рекомендаций