Ответ
Rate Limiter (ограничитель скорости запросов) можно реализовать на нескольких уровнях, и выбор зависит от архитектуры и требований к системе.
Уровни реализации:
-
HTTP Middleware (Промежуточное ПО)
- Описание: Самый распространенный способ для веб-сервисов. Ограничитель встраивается в цепочку обработки HTTP-запросов и проверяет каждый входящий запрос перед тем, как передать его основному обработчику.
-
Пример:
import ( "net/http" "time" "golang.org/x/time/rate" ) func RateLimitMiddleware(next http.Handler) http.Handler { // 10 запросов в секунду с пиковым разрешением до 20 limiter := rate.NewLimiter(10, 20) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !limiter.Allow() { http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) return } next.ServeHTTP(w, r) }) }
-
gRPC Interceptors
- Описание: Аналог Middleware, но для gRPC. Перехватывает входящие RPC-вызовы для применения логики ограничения.
-
На уровне бизнес-логики
- Описание: Используется для ограничения не самих запросов, а ресурсоёмких операций внутри сервиса (например, отправка email, генерация отчетов, сложные вычисления). Это позволяет защитить систему независимо от того, как была вызвана операция (через HTTP, gRPC, CLI или фоновую задачу).
-
На уровне API Gateway / Ingress Controller / Proxy
- Описание: Ограничение настраивается на уровне инфраструктуры (Nginx, Traefik, Kong, облачные API Gateway). Запросы отсекаются еще до того, как достигнут вашего приложения. Это снижает нагрузку на сам сервис.
-
Внешний сервис (Распределенный Rate Limiter)
- Описание: Критически важен для систем с горизонтальным масштабированием (несколько экземпляров сервиса). Чтобы лимит был общим для всех экземпляров, его состояние хранится во внешнем быстром хранилище, чаще всего в Redis.
Популярные инструменты в Go:
golang.org/x/time/rate
: Стандартная библиотека для реализации алгоритма Token Bucket (как в примере выше). Отлично подходит для локальных ограничителей в рамках одного процесса.github.com/go-redis/redis_rate
: Библиотека для создания распределенных ограничителей на базе Redis.github.com/ulule/limiter
: Гибкая библиотека, поддерживающая разные хранилища (in-memory, Redis, Memcached) и фреймворки.