Rate Limiting — это механизм, который ограничивает количество запросов, которые клиент может отправить к серверу за определенный промежуток времени. Этот механизм используется для защиты сервера от перегрузки, предотвращения атак типа "отказ в обслуживании" (DoS) и обеспечения справедливого использования ресурсов.
Ограничение частоты запросов обычно применяется в рамках определенного временного окна, например, 100 запросов в минуту.
Ключ, по которому определяется клиент. Это может быть IP-адрес, API-ключ, идентификатор пользователя и т.д.
Рассмотрим пример реализации Rate Limiting с использованием алгоритма "Токеновый bucket".
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
public class RateLimiter {
private final ConcurrentHashMap<String, AtomicLong> tokens = new ConcurrentHashMap<>();
private final long maxTokens;
private final long refillRate; // токенов в секунду
public RateLimiter(long maxTokens, long refillRate) {
this.maxTokens = maxTokens;
this.refillRate = refillRate;
}
public boolean allowRequest(String key) {
tokens.putIfAbsent(key, new AtomicLong(maxTokens));
AtomicLong tokenBucket = tokens.get(key);
long now = System.currentTimeMillis();
long lastRefillTime = tokenBucket.getAndUpdate(prev -> {
long elapsedTime = now - (prev >> 32);
long newTokens = elapsedTime * refillRate / 1000;
long currentTokens = prev & 0xFFFFFFFFL;
long updatedTokens = Math.min(currentTokens + newTokens, maxTokens);
return (now << 32) | (updatedTokens & 0xFFFFFFFFL);
});
long currentTokens = lastRefillTime & 0xFFFFFFFFL;
if (currentTokens > 0) {
tokenBucket.decrementAndGet();
return true;
}
return false;
}
}
public class RateLimiterExample {
public static void main(String[] args) {
RateLimiter rateLimiter = new RateLimiter(10, 1); // 10 токенов, пополнение 1 токен в секунду
for (int i = 0; i < 15; i++) {
boolean allowed = rateLimiter.allowRequest("client1");
System.out.println("Request " + (i + 1) + " allowed: " + allowed);
try {
Thread.sleep(100); // Задержка между запросами
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Rate Limiting — это важный механизм для защиты серверов от перегрузки и атак. Он может быть реализован с использованием различных алгоритмов, таких как фиксированное окно, скользящее окно и токеновый bucket. В Java Rate Limiting можно реализовать с помощью классов, таких как ConcurrentHashMap
и AtomicLong
, для отслеживания количества запросов и токенов. Правильная настройка Rate Limiting позволяет обеспечить стабильную работу сервера и защитить его от злоупотреблений.