Что такое Rate Limiting?
Rate limiting контролирует, сколько запросов клиент может сделать к API за определённое временное окно. Он защищает серверы от злоупотреблений, обеспечивает справедливое использование и предотвращает DDoS-атаки. Как тестировщик, вам нужно проверить, что rate limit-ы корректно реализованы и что API ясно сообщает о лимитах.
Почему Rate Limiting важен
Без rate limiting один клиент может перегрузить сервер:
- Баг в мобильном приложении, отправляющий запросы в бесконечном цикле
- Злоумышленник, пытающийся скачать все данные
- Неправильно настроенная интеграция с тысячами вызовов в секунду
- Brute-force атаки на endpoint-ы аутентификации
Алгоритмы Rate Limiting
Фиксированное окно (Fixed Window)
Считает запросы в фиксированных временных интервалах. Прост в реализации, но допускает всплески на границах окон.
Скользящее окно (Sliding Window)
Отслеживает запросы за скользящее временное окно. Точнее фиксированного — если вы отправили 80 запросов за последние 60 секунд, у вас осталось 20.
Token Bucket
Токены добавляются в корзину с фиксированной скоростью. Каждый запрос потребляет один токен. Если корзина пуста, запрос отклоняется. Корзина имеет максимальную ёмкость, допуская всплески.
Leaky Bucket
Запросы попадают в очередь (корзину) и обрабатываются с постоянной скоростью. При переполнении новые запросы отклоняются.
| Алгоритм | Обработка всплесков | Точность | Сложность |
|---|---|---|---|
| Фиксированное окно | Всплески на границах | Низкая | Низкая |
| Скользящее окно | Предотвращает всплески | Высокая | Средняя |
| Token Bucket | Контролируемые всплески | Высокая | Средняя |
| Leaky Bucket | Без всплесков | Высокая | Средняя |
Заголовки Rate Limit
Большинство API сообщают о rate limit-ах через заголовки:
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 73
X-RateLimit-Reset: 1625097600
Retry-After: 30
| Заголовок | Значение |
|---|---|
X-RateLimit-Limit | Максимум запросов в окне |
X-RateLimit-Remaining | Оставшиеся запросы в текущем окне |
X-RateLimit-Reset | Unix timestamp сброса окна |
Retry-After | Секунды ожидания перед повтором (при 429) |
Тестирование заголовков Rate Limit
Для каждого успешного ответа проверяйте:
X-RateLimit-Limitприсутствует и соответствует документацииX-RateLimit-Remainingуменьшается на 1 с каждым запросомX-RateLimit-Reset— валидная будущая метка времени- Значения согласованы между последовательными запросами
Тестирование применения Rate Limit
Базовый тест применения
Отправляйте запросы в быстрой последовательности:
import requests
import time
url = "https://api.example.com/data"
headers = {"Authorization": "Bearer token"}
results = []
for i in range(110): # Превысить лимит 100/мин
response = requests.get(url, headers=headers)
results.append({
"request": i + 1,
"status": response.status_code,
"remaining": response.headers.get("X-RateLimit-Remaining")
})
# Проверить: первые 100 — 200, остальные — 429
Тестовые сценарии
| Сценарий | Ожидаемое поведение |
|---|---|
| Нормальное использование | 200 с правильным remaining |
| Точно на лимите | 200 для последнего разрешённого запроса |
| На один выше лимита | 429 с Retry-After |
| После ожидания сброса | 200 с полным лимитом |
| Разные endpoint-ы | Могут иметь отдельные лимиты |
| Разные auth-токены | У каждого пользователя свои лимиты |
| Без аутентификации | Обычно более строгие лимиты по IP |
Тест восстановления
После достижения лимита:
- Проверить, что 429 содержит
Retry-After - Подождать указанное время
- Отправить ещё запрос — должен быть 200
- Проверить сброс
X-RateLimit-Remaining
Лимиты по endpoint vs. глобальные
Некоторые API имеют разные лимиты по endpoint-ам:
- Аутентификация: 5 запросов/минуту
- Чтение: 1000 запросов/минуту
- Запись: 100 запросов/минуту
- Поиск: 30 запросов/минуту
Проверяйте, что лимиты применяются к каждому endpoint-у отдельно.
Распространённые баги Rate Limiting
| Баг | Как обнаружить |
|---|---|
| Лимиты не применяются | Превысить лимит — всё 200 |
| Неверный remaining | Отслеживать X-RateLimit-Remaining |
| Неверное время сброса | Сравнить timestamp с реальным поведением |
| Нет Retry-After при 429 | Проверить заголовки 429 |
| Лимиты сбрасываются при ошибке | Вызвать 400, проверить счётчик |
Практическое упражнение
- Тестируйте лимиты GitHub API: GitHub допускает 60 запросов/час без аутентификации. Отслеживайте заголовки rate limit.
- Определите тип окна: Фиксированное или скользящее — отправляйте всплески на границах окон.
- Тест восстановления: Достигните лимита, дождитесь Retry-After, проверьте восстановление.
- Задокументируйте лимиты: Создайте таблицу всех rate limit-ов тестового API.
Ключевые выводы
- Rate limiting защищает API от злоупотреблений — его тестирование критически важно для продакшна
- Основные алгоритмы: фиксированное окно, скользящее окно, token bucket и leaky bucket
- Всегда проверяйте точность и согласованность заголовков rate limit
- Тестируйте полный цикл: нормальное использование, достижение лимита, получение 429, восстановление
- Лимиты по endpoint-ам, пользователям и IP могут различаться — тестируйте каждый