Zum Inhalt

redis-ratelimit: Begrenzung der Anfrageverarbeitungsrate zwischen mehreren NGINX-Instanzen, die von Redis unterstützt werden

Installation

Wenn Sie das RPM-Repository-Abonnement noch nicht eingerichtet haben, melden Sie sich an. Dann 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-redis-ratelimit

CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-redis-ratelimit

Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.

Dieses Dokument beschreibt lua-resty-redis-ratelimit v0.3, veröffentlicht am 03. Oktober 2019.


Diese Lua-Bibliothek ist ein Modul zur Begrenzung der Anfrageverarbeitungsrate für ngx_lua:

http://wiki.nginx.org/HttpLuaModule

Sie wird verwendet, um die Anfrageverarbeitungsrate pro definiertem Schlüssel zwischen mehreren NGINX-Instanzen zu begrenzen. Die Begrenzung erfolgt mit der Methode "leaky bucket".

Dieses Modul verwendet Redis (>= 2.6.0) als Backend-Speicher, daher benötigen Sie auch die lua-resty-redis Bibliothek, um damit zu arbeiten.

HINWEIS: Wenn Sie die duration-Funktion nicht verwenden und der eingehende Datenverkehr gleichmäßig verteilt ist, wird empfohlen, das Modul resty.limit.req zu verwenden, um unnötige Netzwerkverzögerungen zu vermeiden.

Synopsis

server {

    listen 9090;

    location /t {
        access_by_lua_block {
            local ratelimit = require "resty.redis.ratelimit"

            local lim, err = ratelimit.new("one", "2r/s", 0, 2)
            if not lim then
                ngx.log(ngx.ERR,
                        "Fehler beim Instanziieren eines resty.redis.ratelimit-Objekts: ", err)
                return ngx.exit(500)
            end

            -- HINWEIS: Der folgende Aufruf muss pro Anfrage erfolgen.

            -- local redis = require "resty.redis"
            -- local red = redis:new()

            -- red:set_timeout(1000)

            -- local ok, err = red:connect("127.0.0.1", 6379)
            -- if not ok then
            --     ngx.log(ngx.ERR, "Fehler beim Verbinden mit Redis: ", err)
            --     return ngx.exit(500)
            -- end

            local red = { host = "127.0.0.1", port = 6379, timeout = 1 }

            local key = ngx.var.binary_remote_addr
            local delay, err = lim:incoming(key, red)
            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 übermäßigen Anfragen
                -- pro Sekunde für den angegebenen Schlüssel.
                local excess = err

                ngx.sleep(delay)
            end
        '}

        echo Eingeloggt;
    }

}

Methoden

new

syntax: obj, err = class.new(zone, rate, burst, duration)

Instanziiert ein Objekt dieser Klasse. Der Klassenwert wird durch den Aufruf require resty.redis.ratelimit zurückgegeben.

Diese Methode nimmt die folgenden Argumente:

  • zone: Setzt den Namensraum, insbesondere verwenden wir den <zone>:<key>-String als eindeutigen Statusbezeichner innerhalb von Redis.
  • rate: Die Rate wird in Anfragen pro Sekunde (r/s) angegeben. Wenn eine Rate von weniger als einer Anfrage pro Sekunde gewünscht ist, wird sie in Anfragen pro Minute (r/m) angegeben. Zum Beispiel entspricht eine halbe Anfrage pro Sekunde 30r/m.
  • burst: Definiert, wie viele Anfragen über die von der Zone angegebene Rate hinaus gemacht werden können, Standardwert 0.
  • duration: Die Zeitverzögerung (in Sekunden), bevor der normale Zustand wiederhergestellt wird. Während dieses Zeitraums wird die Anfrage immer rejected, Standardwert 0.

Im Fehlerfall gibt diese Methode nil und eine Zeichenfolge zurück, die den Fehler beschreibt.

incoming

syntax: delay, err = obj:incoming(key, redis)

Löst ein neues Ereignis für eingehende Anfragen aus und berechnet die erforderliche Verzögerung (falls vorhanden) für die aktuelle Anfrage anhand des angegebenen Schlüssels oder ob der Benutzer sie sofort ablehnen sollte.

Diese Methode akzeptiert die folgenden Argumente:

  • key: Der Schlüssel ist jeder nicht leere Wert der angegebenen Variablen.
  • redis: Setzt die Redis-Konfiguration, host, port, timeout usw. (siehe unten); Anstelle der spezifischen Redis-Konfiguration können Sie auch das verbundene Redis-object direkt setzen.
- redis.host: Standard 127.0.0.1.
- redis.port: Standard 80.
- redis.timeout: Standard 1s.
- redis.pass: Anfrage zur Authentifizierung auf einem passwortgeschützten Redis-Server.
- redis.dbid: Wählt die logische Redis-Datenbank aus.

Die Rückgabewerte hängen von den folgenden Fällen ab:

  1. Wenn die Anfrage den in der new-Methode angegebenen rate-Wert nicht überschreitet, gibt diese Methode 0 als Verzögerung und die (null) Anzahl der übermäßigen Anfragen pro Sekunde zum aktuellen Zeitpunkt zurück.
  2. Wenn die Anfrage das in der new-Methode angegebene rate-Limit überschreitet, aber nicht den rate + burst-Wert, gibt diese Methode eine angemessene Verzögerung (in Sekunden) für die aktuelle Anfrage zurück, sodass sie weiterhin dem rate-Schwellenwert entspricht, als ob sie etwas später anstatt jetzt käme. Der 2. Rückgabewert zeigt die Anzahl der übermäßigen Anfragen pro Sekunde zu diesem Zeitpunkt (einschließlich der aktuellen Anfrage) an.
  3. Wenn die Anfrage das rate + burst-Limit überschreitet, gibt diese Methode nil und die Fehlerzeichenfolge "rejected" zurück.
  4. Wenn ein Fehler aufgetreten ist, gibt diese Methode nil und eine Zeichenfolge zurück, die den Fehler beschreibt. Zum Beispiel "Fehler beim Erstellen von Redis - Verbindung abgelehnt".

Diese Methode schläft niemals selbst. Sie gibt einfach eine Verzögerung zurück, falls erforderlich, und erfordert, dass der Aufrufer später die ngx.sleep-Methode aufruft, um zu schlafen.

set_burst

syntax: obj:set_burst(burst)

Überschreibt den burst-Schwellenwert, wie in der new-Methode angegeben.

Siehe auch

GitHub

Sie finden zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-redis-ratelimit.