Traffic limiting scenario: The capability of service provision is limited. To prevent the service from being overwhelmed by a large number of requests, you can limit the flow of service requests through the gateway. For example, a service can process only 100 requests for 1s. The requests exceeding the traffic limit threshold are discarded.
A, rate limiting
The Kong gateway supports rate-limiting
1.1 Configuration Parameters
You can get this information from the plug-in parameters:
- There are three granularity types supported for traffic limiting:
consumer
,credential
,ip
, the default is consumer - Storage policies support the following three types:
local
,cluster
,redis
, the default is Cluster. The stored contents are as followsfmt("ratelimit:%s:%s:%s:%s", api_id, identifier, period_date, name)
Is key, and the number of continuous accesses is value.
- Local: Stores shared content in Nginx – supports interwork access
- Cluster: in the database
rate-limiting
Table in – Cluster access supported - Redis: Plug-in configuration in Redis – supports cluster access
- Supports traffic limiting in various time units
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}},Copy the code
1.2 Current limiting granularity
When the restriction type (restriction granularity) is consumer and identifier, traffic limiting plug-ins need to inject authentication information into nginx.ctx, such as JWT, key-Auth, and 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# If there is no authentication in the request, granularity degrades to IP limitingif not identifier then
identifier = ngx.var.remote_addr
end
Copy the code
1.3 Traffic limiting Algorithm
A common approach to limiting traffic is the number of requests over a period of time. However, if you limit the time by a period of time, you will encounter the problem of uneven flow distribution. For example, if a service has a limit of 3600 requests per hour, then at some point a number of requests come in and exceed the threshold. To solve this problem, Kong took down a period of time, setting the threshold at 60 beats per minute per second.
local limits = {
second = conf.second,
minute = conf.minute,
hour = conf.hour,
day = conf.day,
month = conf.month,
year = conf.year
}
Copy the code
Calculate the remaining. Each time the request comes in, the plugin gets the number of remaining requests from the store and returns the usage format (where name is the Metric of the limits definition mentioned above) :
-- Recording usage
usage[name] = {
limit = limit,
remaining = remaining
}
-- Mark that Metric stopped
if remaining <= 0 then
stop = name
end
Copy the code
Then minus one
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
Copy the code
Second, on limiting the flow
Reference:
- Some implementations of service traffic limiting algorithms are discussed
- Java Concurrency Utility class (Semaphore)
- Redis Deep Adventures: Core Principles and Applied Practices