checkups: Verwalten von NGINX-Upstreams in reinem 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-checkups
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-checkups
Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.
Dieses Dokument beschreibt lua-resty-checkups v0.1, veröffentlicht am 01. Februar 2019.
- Periodische Heartbeats an Upstream-Server
- Proaktive und passive Gesundheitsprüfung
- Dynamisches Update der Upstreams
- Lastverteilung durch gewichtetes Round-Robin oder konsistenten Hash
- Synchronisieren mit Nginx-Upstream-Blöcken
- Cluster nach Ebenen oder Schlüsseln ausprobieren
Synopsis
-- config.lua
_M = {}
_M.global = {
checkup_timer_interval = 15,
checkup_shd_sync_enable = true,
shd_config_timer_interval = 1,
}
_M.ups1 = {
cluster = {
{
servers = {
{ host = "127.0.0.1", port = 4444, weight=10, max_fails=3, fail_timeout=10 },
}
},
},
}
return _M
-- nginx.conf
lua_shared_dict state 10m;
lua_shared_dict mutex 1m;
lua_shared_dict locks 1m;
lua_shared_dict config 10m;
server {
listen 12350;
return 200 12350;
}
server {
listen 12351;
return 200 12351;
}
init_by_lua_block {
local config = require "config"
local checkups = require "resty.checkups.api"
checkups.init(config)
}
init_worker_by_lua_block {
local config = require "config"
local checkups = require "resty.checkups.api"
checkups.prepare_checker(config)
checkups.create_checker()
}
server {
location = /12350 {
proxy_pass http://127.0.0.1:12350/;
}
location = /12351 {
proxy_pass http://127.0.0.1:12351/;
}
location = /t {
content_by_lua_block {
local checkups = require "resty.checkups.api"
local callback = function(host, port)
local res = ngx.location.capture("/" .. port)
ngx.say(res.body)
return 1
end
local ok, err
-- Verbindung zu einem nicht erreichbaren Server, kein Upstream verfügbar
ok, err = checkups.ready_ok("ups1", callback)
if err then ngx.say(err) end
-- Server zu ups1 hinzufügen
ok, err = checkups.update_upstream("ups1", {
{
servers = {
{ host = "127.0.0.1", port = 12350, weight=10, max_fails=3, fail_timeout=10 },
}
},
})
if err then ngx.say(err) end
ngx.sleep(1)
ok, err = checkups.ready_ok("ups1", callback)
if err then ngx.say(err) end
ok, err = checkups.ready_ok("ups1", callback)
if err then ngx.say(err) end
-- Server zu neuem Upstream hinzufügen
ok, err = checkups.update_upstream("ups2", {
{
servers = {
{ host="127.0.0.1", port=12351 },
}
},
})
if err then ngx.say(err) end
ngx.sleep(1)
ok, err = checkups.ready_ok("ups2", callback)
if err then ngx.say(err) end
-- Server zu ups2 hinzufügen, rr-Zustand zurücksetzen
ok, err = checkups.update_upstream("ups2", {
{
servers = {
{ host = "127.0.0.1", port = 12350, weight=10, max_fails=3, fail_timeout=10 },
{ host = "127.0.0.1", port = 12351, weight=10, max_fails=3, fail_timeout=10 },
}
},
})
if err then ngx.say(err) end
ngx.sleep(1)
ok, err = checkups.ready_ok("ups2", callback)
if err then ngx.say(err) end
ok, err = checkups.ready_ok("ups2", callback)
if err then ngx.say(err) end
}
}
}
Eine typische Ausgabe des oben definierten Standorts /t ist:
keine Server verfügbar
12350
12350
12351
12350
12351
Konfiguration
Lua-Konfiguration
Die Konfigurationsdatei von checkups ist ein Lua-Modul, das aus zwei Teilen besteht: dem globalen Teil und dem Clusterteil.
Eine Beispielkonfigurationsdatei von checkups ist unten dargestellt:
-- config.lua
-- Hier ist der globale Teil
_M = {}
_M.global = {
checkup_timer_interval = 15,
checkup_timer_overtime = 60,
default_heartbeat_enable = true,
checkup_shd_sync_enable = true,
shd_config_timer_interval = 1,
}
-- Die restlichen Teile sind Clusterkonfigurationen
_M.redis = {
enable = true,
typ = "redis",
timeout = 2,
read_timeout = 15,
send_timeout = 15,
protected = true,
cluster = {
{ -- Ebene 1
try = 2,
servers = {
{ host = "192.168.0.1", port = 6379, weight=10, max_fails=3, fail_timeout=10 },
{ host = "192.168.0.2", port = 6379, weight=10, max_fails=3, fail_timeout=10 },
}
},
{ -- Ebene 2
servers = {
{ host = "192.168.0.3", port = 6379, weight=10, max_fails=3, fail_timeout=10 },
}
},
},
}
_M.api = {
enable = false,
typ = "http",
http_opts = {
query = "GET /status HTTP/1.1\r\nHost: localhost\r\n\r\n",
statuses = {
["500"] = false,
["502"] = false,
["503"] = false,
["504"] = false,
},
},
mode = "hash",
cluster = {
dc1 = {
servers = {
{ host = "192.168.1.1", port = 1234, weight=10, max_fails=3, fail_timeout=10 },
}
},
dc2 = {
servers = {
{ host = "192.168.1.2", port = 1234, weight=10, max_fails=3, fail_timeout=10 },
}
}
}
}
_M.ups_from_nginx = {
timeout = 2,
cluster = {
{ -- Ebene 1
upstream = "api.com",
},
{ -- Ebene 2
upstream = "api.com",
upstream_only_backup = true,
},
},
}
return _M
Globale Konfigurationen
checkup_timer_interval: Intervall für das Senden von Heartbeats an Backend-Server. Standard ist5.checkup_timer_overtime: Intervall der Prüfungen, um den Timer-Schlüssel ablaufen zu lassen. In den meisten Fällen müssen Sie diesen Wert nicht ändern. Standard ist60.default_heartbeat_enable: Checkups senden standardmäßig Heartbeats an Server oder nicht. Standard isttrue.checkup_shd_sync_enable: Erstellen Sie einen Upstream-Synchronisierer für jeden Worker. Wenn auffalsegesetzt, funktioniert der dynamische Upstream nicht richtig. Standard isttrue.shd_config_timer_interval: Intervall zum Synchronisieren der Upstream-Liste aus dem gemeinsamen Speicher. Standard entsprichtcheckup_timer_interval.ups_status_sync_enable: Wenn auftruegesetzt, synchronisieren Checkups den Upstream-Status von Checkups zu Nginx-Upstream-Blöcken. Standard istfalse.ups_status_timer_interval: Intervall zum Synchronisieren des Upstream-Status von Checkups zu Nginx-Upstream-Blöcken.
Clusterkonfigurationen
skey:_M.xxxxx.xxxxxist derskey(Service-Schlüssel) dieses Clusters.enable: Aktivieren oder Deaktivieren von Heartbeats an Server. Standard isttrue.typ: Cluster-Typ, muss einer vongeneral,redis,mysql,httpsein. Standard istgeneral.general: Heartbeat über TCPsock:connect.redis: Heartbeat über RedisPING. Das lua-resty-redis-Modul ist erforderlich.mysql: Heartbeat über MySQLdb:connect. Das lua-resty-mysql-Modul ist erforderlich.http: Heartbeat über HTTP-Anfrage. Sie können benutzerdefinierte HTTP-Anfragen und Antwortcodes inhttp_optseinrichten.
timeout: Verbindungs-Timeout zu Upstream-Servern. Standard ist5.read_timeout: Lese-Timeout zu Upstream-Servern (nicht während des Heartbeat verwendet). Standard entsprichttimeout.send_timeout: Schreib-Timeout zu Upstream-Servern (nicht während des Heartbeat verwendet). Standard entsprichttimeout.-
http_opts: HTTP-Heartbeat-Konfigurationen. Funktioniert nur fürtyp="http".query: HTTP-Anfrage für Heartbeat.statuses: Wenn der vom Server zurückgegebene Code auffalsegesetzt ist, wird der Server als fehlerhaft betrachtet.
-
mode: Lastverteilungsmodus. Kann aufhash,url_hashoderip_hashgesetzt werden. Checkups werden Server nachhash_key,ngx.var.urioderngx.var.remote_addrausbalancieren. Standard istwrr. protected: Wenn auftruegesetzt und alle Server im Cluster fehlerhaft sind, wird Checkups den letzten fehlerhaften Server nicht als nicht verfügbar (err) markieren, sondern alsunstable(im nächsten Versuch weiterhin verfügbar). Standard isttrue.-
cluster: Sie können mehrere Ebenen entsprechend der Cluster-Priorität konfigurieren. Auf jeder Ebene können Sie ein Cluster vonserverskonfigurieren. Checkups versuchen die nächste Ebene nur, wenn alle Server in der vorherigen Ebene als nicht verfügbar betrachtet werden.Anstatt Cluster nach Ebenen auszuprobieren, können Sie Checkups so konfigurieren, dass sie Cluster nach Schlüssel ausprobieren (siehe oben
api-Cluster). Denken Sie daran, dass Sie auch ein zusätzliches Argument wieopts.cluster_key={"dc1", "dc2"}oderopts.cluster_key={3, 1, 2}an checkups.read_ok übergeben sollten, damit Checkups in der Reihenfolgedc1,dc2oderEbene 3,Ebene 1,Ebene 2versuchen. Wenn Sieopts.cluster_keynicht an checkups.ready_ok übergeben haben, wird Checkups weiterhin versuchen, Cluster nach Ebenen auszuprobieren. Für den oben genanntenapi-Cluster wird Checkups schließlichkeine Server verfügbarzurückgeben. *try: Anzahl der Wiederholungen. Standard ist die Anzahl der Server. *try_timeout: Begrenzung der Zeit, während der eine Anfrage beantwortet werden kann, ähnlich wie nginxproxy_next_upstream_timeout. *servers: Konfiguration fürserversist wie folgt aufgeführt, *weight: Setzt das Gewicht des Servers. Standard ist1. *max_fails: Setzt die Anzahl der erfolglosen Versuche, mit dem Server zu kommunizieren, die innerhalb der Zeit, die durch den Parameterfail_timeoutfestgelegt ist, erfolgen sollten. Standardmäßig ist die Anzahl der erfolglosen Versuche auf0gesetzt, was die Zählung der Versuche deaktiviert. Was als erfolgloser Versuch betrachtet wird, wird durchhttp_opts.statusesdefiniert, wenntyp="http"oder einnil/falsevon checkups.ready_ok zurückgegeben wird. Diese Option ist nur im Round-Robin verfügbar. *fail_timeout: Setzt die Zeit, während der die angegebene Anzahl von erfolglosen Versuchen, mit dem Server zu kommunizieren, stattfinden sollte, um den Server als nicht verfügbar zu betrachten, und die Zeitspanne, in der der Server als nicht verfügbar betrachtet wird. Standardmäßig ist der Parameter auf10Sekunden eingestellt. Diese Option ist nur im Round-Robin verfügbar.upstream: Name der Nginx-Upstream-Blöcke. Checkups extrahieren Server aus den Upstream-Blöcken der Nginx-Konfiguration in prepare_checker. Das lua-upstream-nginx-module-Modul ist erforderlich.upstream_only_backup: Wenn auftruegesetzt, extrahiert Checkups nur Backup-Server aus den Nginx-Upstream-Blöcken.
Nginx-Konfiguration
Fügen Sie die Pfade der Lua-Konfigurationsdatei und von Checkups zu lua_package_path hinzu und erstellen Sie die von Checkups verwendeten Lua Shared Dicts. Sie sollten diese Zeilen in den http-Block Ihrer Nginx-Konfigurationsdatei einfügen.
lua_shared_dict state 10m;
lua_shared_dict mutex 1m;
lua_shared_dict locks 1m;
lua_shared_dict config 10m;
Wenn Sie das Stream-Subsystem verwenden, sollten Sie diese Zeilen in den stream-Block Ihrer Nginx-Konfigurationsdatei einfügen.
lua_shared_dict stream_state 10m;
lua_shared_dict stream_mutex 1m;
lua_shared_dict stream_locks 1m;
lua_shared_dict stream_config 10m;
API

init
syntax: init(config)
phase: init_by_lua
Kopiert Upstreams von config.lua in shdict, extrahiert Server aus Nginx-Upstream-Blöcken und führt einige grundlegende Initialisierungen durch.
prepare_checker
syntax: prepare_checker(config)
phase: init_worker_by_lua
Kopiert Konfigurationen von config.lua zu Worker-Checkups, extrahiert Server aus Nginx-Upstream-Blöcken und führt einige grundlegende Initialisierungen durch.
create_checker
syntax: create_checker()
phase: init_worker_by_lua
Erstellt einen Heartbeat-Timer und einen Upstream-Synchronisationstimer. Es wird nur ein Heartbeat-Timer unter allen Workern erstellt. Es wird dringend empfohlen, diese Methode in der Phase init_worker aufzurufen.
ready_ok
syntax: res, err = ready_ok(skey, callback, opts?)
phase: rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*
Wählt einen verfügbaren peer aus dem Cluster skey aus und ruft callback(peer.host, peer.port, opts) auf.
Die opts-Tabelle akzeptiert die folgenden Felder,
cluster_key: Versuchen Sie, Cluster nachcluster_keyzu gruppieren. Checkups werden Cluster in der Reihenfolge descluster_keyversuchen.clusters_keykann der Name der Cluster oder die Ebene der Cluster sein. Cluster z.B.:{"cluster_name_A", "name_B", "name_C"}. Ebenen z.B.:{3, 2, 1}.hash_key: Schlüssel, der im Hash-Balancemodus verwendet wird. Wenn nicht gesetzt, wirdngx.var.uriverwendet.try: Die Wiederholungen werden nicht mehr alstry-Mal sein.try_timeout: Begrenzung der Zeit, während der eine Anfrage beantwortet werden kann, ähnlich wie nginxproxy_next_upstream_timeout.
Gibt das zurück, was callback bei Erfolg zurückgibt, oder gibt nil und eine Beschreibung des Fehlers zurück, wenn nicht.
Wenn callback nil oder false zurückgibt, wird Checkups dies als fehlgeschlagenen Versuch betrachten und callback mit einem anderen Peer erneut versuchen. Denken Sie also immer daran, nach einem erfolgreichen Callback nicht nil oder false zurückzugeben.
select_peer
syntax: peer, err = select_peer(skey)
context: rewrite_by_lua*, access_by_lua*, content_by_lua*, balancer_by_lua
Wählt einen verfügbaren Peer aus dem Cluster skey aus.
Gibt eine Tabelle mit host und port eines verfügbaren Peers zurück.
Im Falle von Fehlern gibt es nil mit einer Beschreibung des Fehlers zurück.
get_status
syntax: status = get_status()
phase: rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*
Gibt den Status von Checkups im json-Format zurück.
get_ups_timeout
syntax: connect_timeout, send_timeout, read_timeout = get_ups_timeout(skey)
phase: rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*
Gibt das Timeout des Clusters skey zurück.
feedback_status
syntax: ok, err = feedback_status(skey, host, port, failed)
context: rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, balancer_by_lua.*
Markiert den Server host:port im Cluster skey als fehlgeschlagen (true) oder verfügbar (false).
Gibt 1 bei Erfolg zurück oder gibt nil und eine Beschreibung des Fehlers zurück, wenn nicht.
update_upstream
syntax: ok, err = update_upstream(skey, upstream)
phase: rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*
Aktualisiert den Cluster skey. upstream hat dasselbe Format wie cluster in config.lua.
Gibt true bei Erfolg zurück oder gibt false und eine Beschreibung des Fehlers zurück, wenn nicht.
delete_upstream
syntax: ok, err = delete_upstream(skey)
phase: rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*
Löscht den Cluster skey aus der Upstream-Liste.
Gibt true bei Erfolg zurück oder gibt false und eine Beschreibung des Fehlers zurück, wenn nicht.
Siehe auch
GitHub
Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-checkups.