Обмеження частоти запитів
OxPHP має вбудований обмежувач частоти запитів за IP-адресою, тож вам не потрібні зовнішні залежності чи окрема інфраструктура. Після ввімкнення він рахує запити від кожної клієнтської IP-адреси й повертає відповідь 429 Too Many Requests, щойно клієнт перевищує налаштований поріг.
Як це працює
Обмежувач використовує лічильник із фіксованим вікном, прив’язаний до IP-адреси клієнта. Кожна IP-адреса має власний незалежний лічильник і власне вікно.
- Коли надходить запит, OxPHP шукає IP-адресу клієнта у своєму внутрішньому трекері.
- Якщо запису немає або поточне вікно вже минуло, починається нове вікно з нульовим лічильником.
- Лічильник збільшується з кожним запитом.
- Якщо лічильник перевищує
RATE_LIMIT, сервер одразу повертає відповідь429із заголовками rate limit. Запит відхиляється ще до маршрутизації та виконання PHP.
Обмежені запити все одно потрапляють до журналів доступу та метрик.
Налаштування
| Змінна | Типове значення | Опис |
|---|---|---|
RATE_LIMIT |
0 |
Максимальна кількість запитів з однієї IP-адреси в межах вікна. 0 повністю вимикає обмеження без жодних накладних витрат |
RATE_WINDOW_SECONDS |
60 |
Тривалість вікна обмеження в секундах |
# Allow 100 requests per IP per 60-second window
RATE_LIMIT=100
RATE_WINDOW_SECONDS=60Заголовки відповіді
Відхилені запити отримують відповідь 429 Too Many Requests з такими заголовками:
| Заголовок | Опис |
|---|---|
Retry-After |
Кількість секунд до скидання поточного вікна |
x-ratelimit-limit |
Максимальна дозволена кількість запитів за вікно |
x-ratelimit-remaining |
Скільки запитів лишилося в поточному вікні (0, коли ліміт вичерпано) |
x-ratelimit-reset |
Кількість секунд до скидання поточного вікна |
x-request-id |
Ідентифікатор запиту, щоб зіставити цю відповідь із журналами доступу |
Приклад відповіді 429:
HTTP/1.1 429 Too Many Requests
Retry-After: 45
x-ratelimit-limit: 100
x-ratelimit-remaining: 0
x-ratelimit-reset: 45
x-request-id: 67e2a1f412341a2b0042
429 Too Many RequestsУсунення несправностей
Обмеження зачіпає звичайних користувачів
Можливо, ваш поріг занадто низький для реального трафіку. Перевірте частку відповідей 429 у метриках і відповідно змініть RATE_LIMIT або RATE_WINDOW_SECONDS.
Перевірте кількість обмежених запитів:
curl http://localhost:9090/metrics | grep rate_limitedРішення: збільште RATE_LIMIT або подовжте RATE_WINDOW_SECONDS, щоб дати клієнтам більше простору.
Користувачі за корпоративним NAT ділять один лічильник IP
OxPHP обмежує частоту за IP-адресою джерела. Усі користувачі за спільним NAT чи проксі ділять один лічильник. Якщо це спричиняє проблеми, вимкніть вбудований обмежувач OxPHP (RATE_LIMIT=0) і застосуйте обмеження на вищому рівні (наприклад, на балансувальнику навантаження чи API-шлюзі), де вам доступні ідентифікатори користувачів.
Задайте TRUSTED_PROXIES, щоб обмеження спиралося на справжню IP-адресу клієнта, а не на IP-адресу проксі. Див. Довірені проксі.
Обмеження не працює між кількома екземплярами
Обмежувач OxPHP зберігає стан у пам’яті окремо для кожного екземпляра. Якщо ви запускаєте кілька екземплярів OxPHP за балансувальником навантаження, кожен веде власні незалежні лічильники. Клієнт може надіслати RATE_LIMIT запитів на кожен екземпляр, не отримавши 429. Для узгодженого обмеження між екземплярами використовуйте зовнішній обмежувач на рівні балансувальника навантаження чи API-шлюзу.
Пам’ять зростає під час атак із ротацією IP
OxPHP відстежує до 100 000 унікальних IP-адрес. Коли цю межу досягнуто, прострочені записи видаляються перед додаванням нових. Якщо ви бачите зростання пам’яті через те, що зловмисник швидко змінює IP-адреси, автоматичне очищення обмежує вплив фіксованим обсягом пам’яті.
Приклад для Docker
services:
app:
image: ghcr.io/oxphp/oxphp:0.13.0
ports:
- "8080:80"
environment:
RATE_LIMIT: "100"
RATE_WINDOW_SECONDS: "60"
volumes:
- ./app:/var/www/html:roРекомендації
- Починайте обережно. Задайте спершу нижчий ліміт (наприклад, 60 запитів на хвилину) і підвищуйте його з огляду на реальний трафік. Послабити ліміти легше, ніж відновити перевантажений сервер.
- Для розгортань із кількома екземплярами використовуйте спільний обмежувач. Обмежувач OxPHP працює в межах одного екземпляра. Для узгодженого обмеження між екземплярами застосуйте його на рівні балансувальника навантаження чи API-шлюзу.
- Стежте за часткою відповідей 429. Відстежуйте в метриках частку обмежених запитів, щоб помітити хибно налаштовані пороги чи несподівані сплески трафіку.
Примітки
- Алгоритм фіксованого вікна. Обмежувач використовує лічильник із фіксованим, а не ковзним вікном. На межі двох вікон клієнт може надіслати сплеском до
2xвід налаштованого ліміту. - Лише за IP-адресою. Ключем обмеження є IP-адреса джерела. Власні ключі, як-от API-ключ чи ідентифікатор користувача, не підтримуються.
- Стан у пам’яті. Лічильники не спільні між кількома екземплярами OxPHP.
- Автоматичне очищення. Коли трекер перевищує 100 000 IP-адрес, з нього видаляються всі записи з простроченими вікнами.
Промпти для вашого агента
Ці промпти розраховані на агента з підключеним MCP-сервером документації OxPHP — потрібні сторінки він прочитає сам.
Налаштуй обмеження частоти запитів для мого розгортання OxPHP. Прочитай сторінку `features/rate-limiting` через MCP-сервер документації OxPHP.
Переглянь ендпоінти, які відкриває цей репозиторій, і трафік, що припадає на один екземпляр, обери ліміт і вікно та скажи, чи вистачить обмежувача на рівні екземпляра для мого способу розгортання.Див. також
- Метрики — моніторинг кількості обмежених запитів через Prometheus
- Ідентифікатори запитів — зіставлення обмежених запитів у журналах
- Журнали доступу — відповіді 429 потрапляють до журналів доступу
- Довідник налаштувань — повний перелік змінних оточення