Rate Limiting
Волга предоставляет встроенную высокопроизводительную систему ограничения скорости запросов, разработанную для HTTP API и микросервисов. Она поддерживает несколько алгоритмов, гибкие partition keys и может применяться глобально, для каждой группы маршрутов или для каждого маршрута отдельно.
В этом руководстве демонстрируется базовое использование алгоритма Фиксированного окна.
Включение Rate Limiting
Rate Limiting - это дополнительная функция.
Ее необходимо включить явно в Cargo.toml:
[dependencies]
volga = { version = "...", features = ["rate-limiting"] }
Или включите набор функций full:
[dependencies]
volga = { version = "...", features = ["full"] }
Основные Концепции
Прежде чем перейти к примерам, полезно понять основные составляющие:
Политика Rate Limiting
Политика определяет:
- Алгоритм ограничения скорости запросов (например, фиксированное окно)
- Максимальное количество запросов
- Длительность окна
- Опциональное поведение вытеснения
- Опциональное имя
Политики настраиваются один раз на уровне приложения.
Partition Key
Partition key определяет, как группируются запросы.
Типичные примеры:
- IP-адрес клиента
- Аутентифицированный пользователь
- Ключ API
- Параметр запроса или пути
Волга предоставляет вспомогательные функции в рамках volga::rate_limiting::by.
Где можно применять Rate Limiting
Middleware для rate limiting может быть подключено:
- Глобально (ко всему приложению)
- Группе маршрутов
- Отдельному маршруту
Определение политики фиксированного окна
Rate Limiter с фиксированным окном разрешает до N запросов за временное окно.
use std::time::Duration;
use volga::rate_limiting::FixedWindow;
let fixed_window = FixedWindow::new(100, Duration::from_secs(30));
Эта политика разрешает 100 запросов за 30 секунд.
Именованные политики
Политики могут быть именованы и использованы повторно:
let burst = FixedWindow::new(100, Duration::from_secs(30))
.with_name("burst");
Именованные политики полезны, когда разные маршруты требуют разных ограничений.
Регистрация политики
Политики регистрируются в приложении:
use volga::App;
let mut app = App::new()
.with_fixed_window(burst);
На этом этапе политика существует, но еще не активна.
Применение Rate Limiting
Глобальный Rate Limiting
Применить rate limiting ко всем входящим запросам можно вот так:
use volga::rate_limiting::by;
app.use_fixed_window(by::ip());
Это ограничивает все запросы на основе IP-адреса клиента.
Использование именованных политик
Вот так можно использовать конкретную именованную политику:
app.use_fixed_window(by::ip().using("burst"));
Route-Level Rate Limiting
Rate limiting можно применять и к отдельным маршрутам:
app.map_get("/upload", upload_handler)
.fixed_window(by::ip());
Или с помощью именованной политики:
app.map_get("/upload", upload_handler)
.fixed_window(by::ip().using("burst"));
Rate Limiting для групп маршрутов
Rate Limiting также может применяться к группе маршрутов:
app.group("/api", |api| {
api.fixed_window(by::ip());
api.map_get("/status", status_handler);
api.map_post("/upload", upload_handler);
});
Примеры Partition Key
Волга предоставляет встроенные вспомогательные функции:
by::ip() // IP-адрес клиента
by::header("x-api-key") // Пользовательский HTTP-заголовок
by::query("tenant_id") // Параметр запроса
by::path("user_id") // Параметр пути
При включенной функции аутентификации:
by::user(|claims| claims.sub.as_str())
Вы также можете комбинировать несколько ключей, используя слои middleware.
Прочие алгоритмы
В дополнение к Фиксированному окну, Волга поддерживает:
- Скользящее окно – более плавное распределение запросов
- (Планируется добавление других алгоритмов)
Шаблон использования остается тем же:
.with_sliding_window(...)
.sliding_window(by::ip())
Полный пример можно посмотреть здесь.