Сценарии ограничения тока. Возможности, предоставляемые службой, ограничены. Чтобы большое количество запросов не тормозило сервис, можно ограничить поток запросов к сервису через шлюз. Например, служба может обрабатывать только 100 запросов в секунду, а запросы, превышающие текущий предельный порог, отбрасываются.
1. ограничение скорости
Плагины ограничения тока, предоставляемые Kong gateway:rate-limiting
1.1 Настраиваемые параметры
Эту информацию можно получить из параметров плагина:
- Существует три степени детализации поддержки регулирования:
consumer,credential,ip, по умолчанию используется потребительский - Существует три поддерживаемых политики хранения:
local,cluster,redis, по умолчанию используется кластер. Сохраняемый контент:fmt("ratelimit:%s:%s:%s:%s", api_id, identifier, period_date, name)является ключом, а количество непрерывных доступов является значением.
- local: хранит общий контент в Nginx — поддерживает межпроцессный доступ с несколькими рабочими процессами.
- кластер: в базе данных
rate-limitingТаблица — Поддержка доступа к кластеру - redis: плагин, настроенный в Redis — поддерживает доступ к кластеру
- Поддерживает ограничение тока для различных единиц времени
fields = {
second = { type = "number" },
minute = { type = "number" },
hour = { type = "number" },
day = { type = "number" },
month = { type = "number" },
year = { type = "number" },
limit_by = { type = "string", enum = {"consumer", "credential", "ip"}, default = "consumer" },
policy = { type = "string", enum = {"local", "cluster", REDIS}, default = "cluster" },
fault_tolerant = { type = "boolean", default = true },
redis_host = { type = "string" },
redis_port = { type = "number", default = 6379 },
redis_password = { type = "string" },
redis_timeout = { type = "number", default = 2000 },
redis_database = { type = "number", default = 0 },
hide_client_headers = { type = "boolean", default = false },
},
1.2 Детализация ограничения тока
Когда тип ограничения (детализация ограничения)consumerиidentifierКогда подключаемому модулю ограничения тока требуется некотороеnginx.ctxПлагины, которые вводят информацию для аутентификации, например: jwt, key-auth, oauth2
if conf.limit_by == "consumer" then
identifier = ngx.ctx.authenticated_consumer and ngx.ctx.authenticated_consumer.id
if not identifier and ngx.ctx.authenticated_credential then -- Fallback on credential
identifier = ngx.ctx.authenticated_credential.id
end
elseif conf.limit_by == "credential" then
identifier = ngx.ctx.authenticated_credential and ngx.ctx.authenticated_credential.id
end
# 如果请求中不带认证,粒度会退化到IP限流
if not identifier then
identifier = ngx.var.remote_addr
end
1.3 Алгоритм ограничения тока
Обычной практикой дросселирования является количество запросов за период времени. Однако если для ограничения времени используется только определенный период времени, возникает проблема неравномерного распределения трафика. Например, если сервис ограничивает количество запросов в час до 3600, то если куча запросов превысит порог в определенный момент. Чтобы решить эту проблему, Конг разделил период времени и установил пороговое значение 60 раз в секунду.
local limits = {
second = conf.second,
minute = conf.minute,
hour = conf.hour,
day = conf.day,
month = conf.month,
year = conf.year
}
Рассчитать оставшееся. Каждый раз, когда приходит запрос, плагин получает количество обращений к текущему сервису, оставшееся (оставшееся) от хранилища, и возвращаетusageформат (где имя указано вышеlimitsопределенная метрика):
-- Recording usage
usage[name] = {
limit = limit,
remaining = remaining
}
-- 标记那个Metric停止了
if remaining <= 0 then
stop = name
end
затем вычесть один
if usage then
-- Adding headers
if not conf.hide_client_headers then
for k, v in pairs(usage) do
ngx.header[RATELIMIT_LIMIT .. "-" .. k] = v.limit
-- -increment_value for this current request
ngx.header[RATELIMIT_REMAINING .. "-" .. k] = math.max(0, (stop == nil or stop == k) and v.remaining - 1 or v.remaining)
end
end
2. Расскажите о текущем лимите
Ссылаться на: