limit-traffic: Lua-Bibliothek zur Begrenzung und Kontrolle des Verkehrs im nginx-module-lua
Installation
Wenn Sie noch kein RPM-Repository-Abonnement eingerichtet haben, melden Sie sich an. Danach können Sie mit den folgenden Schritten fortfahren.
CentOS/RHEL 7 oder Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-limit-traffic
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-limit-traffic
Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.
Dieses Dokument beschreibt lua-resty-limit-traffic v0.9, das am 08. August 2023 veröffentlicht wurde.
## demonstrieren der Verwendung des resty.limit.req Moduls (allein!)
http {
lua_shared_dict my_limit_req_store 100m;
server {
location / {
access_by_lua_block {
-- nun, wir könnten die require() und new() Aufrufe in unsere eigenen Lua
-- Module setzen, um Overhead zu sparen. Hier setzen wir sie nur zur
-- Bequemlichkeit darunter.
local limit_req = require "resty.limit.req"
-- die Anfragen unter 200 req/sec mit einem Burst von 100 req/sec begrenzen,
-- das heißt, wir verzögern Anfragen unter 300 req/sec und über 200
-- req/sec und lehnen alle Anfragen ab, die 300 req/sec überschreiten.
local lim, err = limit_req.new("my_limit_req_store", 200, 100)
if not lim then
ngx.log(ngx.ERR,
"Fehler beim Instanziieren eines resty.limit.req Objekts: ", err)
return ngx.exit(500)
end
-- der folgende Aufruf muss pro Anfrage erfolgen.
-- hier verwenden wir die Remote (IP) Adresse als das begrenzende Schlüssel
local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, true)
if not delay then
if err == "rejected" then
return ngx.exit(503)
end
ngx.log(ngx.ERR, "Fehler beim Begrenzen der Anfragen: ", err)
return ngx.exit(500)
end
if delay >= 0.001 then
-- der 2. Rückgabewert enthält die Anzahl der überschüssigen Anfragen
-- pro Sekunde für den angegebenen Schlüssel. Zum Beispiel bedeutet die Zahl 31
-- dass die aktuelle Anfragequote bei 231 req/sec für den
-- angegebenen Schlüssel liegt.
local excess = err
-- die Anfrage überschreitet die 200 req/sec, liegt aber unter 300 req/sec,
-- daher verzögern wir sie hier absichtlich ein wenig, um der
-- Rate von 200 req/sec zu entsprechen.
ngx.sleep(delay)
end
}
# Inhaltshandler kommt hierhin. Wenn es content_by_lua ist, können Sie
# den oben stehenden Lua-Code in access_by_lua in den Lua-Handler Ihres
# content_by_lua integrieren, um ein wenig CPU-Zeit zu sparen.
}
}
}
## demonstrieren der Verwendung des resty.limit.conn Moduls (allein!)
http {
lua_shared_dict my_limit_conn_store 100m;
server {
location / {
access_by_lua_block {
-- nun, wir könnten die require() und new() Aufrufe in unsere eigenen Lua
-- Module setzen, um Overhead zu sparen. Hier setzen wir sie nur zur
-- Bequemlichkeit darunter.
local limit_conn = require "resty.limit.conn"
-- die Anfragen unter 200 gleichzeitigen Anfragen (normalerweise nur
-- eingehende Verbindungen, es sei denn, Protokolle wie SPDY werden verwendet) mit
-- einem Burst von 100 zusätzlichen gleichzeitigen Anfragen begrenzen, das heißt, wir verzögern
-- Anfragen unter 300 gleichzeitigen Verbindungen und über 200
-- Verbindungen und lehnen alle neuen Anfragen ab, die 300
-- Verbindungen überschreiten.
-- außerdem gehen wir von einer standardmäßigen Anfragezeit von 0,5 Sek. aus, die durch
-- den leaving() Aufruf in log_by_lua unten dynamisch angepasst werden kann.
local lim, err = limit_conn.new("my_limit_conn_store", 200, 100, 0.5)
if not lim then
ngx.log(ngx.ERR,
"Fehler beim Instanziieren eines resty.limit.conn Objekts: ", err)
return ngx.exit(500)
end
-- der folgende Aufruf muss pro Anfrage erfolgen.
-- hier verwenden wir die Remote (IP) Adresse als das begrenzende Schlüssel
local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, true)
if not delay then
if err == "rejected" then
return ngx.exit(503)
end
ngx.log(ngx.ERR, "Fehler beim Begrenzen der Anfragen: ", err)
return ngx.exit(500)
end
if lim:is_committed() then
local ctx = ngx.ctx
ctx.limit_conn = lim
ctx.limit_conn_key = key
ctx.limit_conn_delay = delay
end
-- der 2. Rückgabewert enthält das aktuelle Niveau der Gleichzeitigkeit
-- für den angegebenen Schlüssel.
local conn = err
if delay >= 0.001 then
-- die Anfrage überschreitet das Verhältnis von 200 Verbindungen, liegt aber unter
-- 300 Verbindungen, daher
-- verzögern wir sie hier absichtlich ein wenig, um der
-- Begrenzung von 200 Verbindungen zu entsprechen.
-- ngx.log(ngx.WARN, "verzögere")
ngx.sleep(delay)
end
}
# Inhaltshandler kommt hierhin. Wenn es content_by_lua ist, können Sie
# den oben stehenden Lua-Code in access_by_lua in Ihren
# content_by_lua Lua-Handler integrieren, um ein wenig CPU-Zeit zu sparen.
log_by_lua_block {
local ctx = ngx.ctx
local lim = ctx.limit_conn
if lim then
-- wenn Sie ein Upstream-Modul in der Inhaltsphase verwenden,
-- möchten Sie wahrscheinlich $upstream_response_time
-- anstelle von ($request_time - ctx.limit_conn_delay) unten verwenden.
local latency = tonumber(ngx.var.request_time) - ctx.limit_conn_delay
local key = ctx.limit_conn_key
assert(key)
local conn, err = lim:leaving(key, latency)
if not conn then
ngx.log(ngx.ERR,
"Fehler beim Aufzeichnen der Verbindung, die die ",
"Anfrage verlässt: ", err)
return
end
end
}
}
}
}
## demonstrieren der Verwendung des resty.limit.traffic Moduls
http {
lua_shared_dict my_req_store 100m;
lua_shared_dict my_conn_store 100m;
server {
location / {
access_by_lua_block {
local limit_conn = require "resty.limit.conn"
local limit_req = require "resty.limit.req"
local limit_traffic = require "resty.limit.traffic"
local lim1, err = limit_req.new("my_req_store", 300, 200)
assert(lim1, err)
local lim2, err = limit_req.new("my_req_store", 200, 100)
assert(lim2, err)
local lim3, err = limit_conn.new("my_conn_store", 1000, 1000, 0.5)
assert(lim3, err)
local limiters = {lim1, lim2, lim3}
local host = ngx.var.host
local client = ngx.var.binary_remote_addr
local keys = {host, client, client}
local states = {}
local delay, err = limit_traffic.combine(limiters, keys, states)
if not delay then
if err == "rejected" then
return ngx.exit(503)
end
ngx.log(ngx.ERR, "Fehler beim Begrenzen des Verkehrs: ", err)
return ngx.exit(500)
end
if lim3:is_committed() then
local ctx = ngx.ctx
ctx.limit_conn = lim3
ctx.limit_conn_key = keys[3]
end
print("schlafe ", delay, " sec, zustände: ",
table.concat(states, ", "))
if delay >= 0.001 then
ngx.sleep(delay)
end
}
# Inhaltshandler kommt hierhin. Wenn es content_by_lua ist, können Sie
# den oben stehenden Lua-Code in access_by_lua in Ihren
# content_by_lua Lua-Handler integrieren, um ein wenig CPU-Zeit zu sparen.
log_by_lua_block {
local ctx = ngx.ctx
local lim = ctx.limit_conn
if lim then
-- wenn Sie ein Upstream-Modul in der Inhaltsphase verwenden,
-- möchten Sie wahrscheinlich $upstream_response_time
-- anstelle von $request_time unten verwenden.
local latency = tonumber(ngx.var.request_time)
local key = ctx.limit_conn_key
assert(key)
local conn, err = lim:leaving(key, latency)
if not conn then
ngx.log(ngx.ERR,
"Fehler beim Aufzeichnen der Verbindung, die die ",
"Anfrage verlässt: ", err)
return
end
end
}
}
}
}
Beschreibung
Diese Bibliothek bietet mehrere Lua-Module, um OpenResty/ngx_lua-Benutzern zu helfen, den Verkehr zu kontrollieren und zu begrenzen, entweder die Anfragequote oder die Anfragegleichzeitigkeit (oder beides).
- resty.limit.req bietet eine Begrenzung der Anfragequote und Anpassungen basierend auf der "leaky bucket"-Methode.
- resty.limit.count bietet eine Begrenzung der Quote basierend auf einer "fixed window"-Implementierung seit OpenResty 1.13.6.1+.
- resty.limit.conn bietet eine Begrenzung des Niveaus der Anfragegleichzeitigkeit und Anpassungen basierend auf zusätzlichen Verzögerungen.
- resty.limit.traffic bietet einen Aggregator, um mehrere Instanzen der resty.limit.req, resty.limit.count oder resty.limit.conn Klassen (oder alle) zu kombinieren.
Bitte sehen Sie sich die eigene Dokumentation dieser Lua-Module für weitere Details an.
Diese Bibliothek bietet flexiblere Alternativen zu den Standardmodulen von NGINX
ngx_limit_req
und ngx_limit_conn.
Zum Beispiel können die von dieser Bibliothek bereitgestellten Lua-basierten Begrenzungen in jedem Kontext verwendet werden,
wie direkt vor dem SSL-Handschlagverfahren (wie bei ssl_certificate_by_lua)
oder direkt vor der Ausgabe von Backend-Anfragen.
nginx.conf
http { ... }
und laden Sie dann eines der von dieser Bibliothek bereitgestellten Module in Lua. Zum Beispiel,
```lua
local limit_req = require "resty.limit.req"
Siehe auch
- Modul resty.limit.req
- Modul resty.limit.count
- Modul resty.limit.conn
- Modul resty.limit.traffic
- das ngx_lua Modul: https://github.com/openresty/lua-nginx-module
- OpenResty: https://openresty.org/
GitHub
Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-limit-traffic.