Stellen Sie sich vor: 02:17, nächtlicher Höhepunkt. Ein Upstream ist am Ende, die Warteschlange wächst, die Analytik bittet darum, eine neue Funktion nur für einen Teil des Datenverkehrs einzuschalten, und das Marketing verlangt, die Geschwindigkeit der Seiten nicht zu verlieren. Die Lösung liegt nicht im Backend. Die Lösung liegt am „Rand“: Nginx mit Lua, plus ein schnelles „Status-Notizbuch“ – Redis. In Millisekunden schalten Sie das Feature-Flag ein, leiten Anfragen um, beschränken „gesprächige“ Clients und geben den Cache zurück, wo es sicher ist. ⚡
Lua in Nginx ist ein Mini-Gehirn direkt an der Haustür Ihres Dienstes: Es sieht Header, Cookies, seltsame Muster, spricht mit Redis und trifft kleine, aber kritische Entscheidungen, bevor die Anfrage die Anwendung erreicht. Redis bietet Atomarität und Geschwindigkeit: Zähler, Quoten, Flags, Idempotenz – ohne Rennen und schwere Transaktionen.

🧠 Warum genau Lua am Rande
⚡ Geschwindigkeit und nicht blockierende E/A: OpenResty/ngx_lua arbeiten in einem Ereignismodell ohne Sperren.
🧩 Einbettbarkeit: Skripte steuern das Verhalten direkt in den Nginx-Phasen (rewrite/access/header/body/log).
🔒 Atomarität in Redis: Lua-Skripte werden als eine einzige Operation ausgeführt (keine Datenrennen).
Die Schlüsselidee: „Ein wenig Logik am Eingang“ spart Backend-Ressourcen und ermöglicht eine feine Steuerung.
🌐 Unerwartete Anwendungen in Nginx + Lua
🎛️ Edge-feature flags: Wir aktivieren die Funktionen nach Segmenten (Land, Client-Version), bevor wir die Anwendung aufrufen.
🧭 Intelligentes Routing: Wir leiten den Traffic nach Abonnementplänen/AB-Varianten weiter, lesen die Regeln aus Redis.
🛡️ Mikro-WAF: "Weiche" Sperren basierend auf Verhaltenssignaturen, ohne legitime Benutzer zu stören.
🧯 Leistungsschalter am Eingang: Wir schneiden den erkrankten Upstream vorübergehend ab, geben einen Cache/eine Platzhalterdatei an.
🧹 URL-Normalisierung: Kanonisierung, Komprimierung von Junk-Abfragen, Kampf gegen Duplikate für den Cache.
🔗 Wie das mit Redis zusammenhängt
🏷️ Flags/Regeln leben in Redis mit TTL → sofortige Verteilung ohne Neustart von Nginx.
🧪 A/B: Die Benutzeroption wird in Redis gespeichert → Konsistenz zwischen Anfragen.
🚦 Rate limiting: Token-Buckets/Leaky-Buckets für Schlüssel
IP+endpointoderuser_id.🔁 Request coalescing: eine Anfrage an den Backend, die anderen warten (wir dämpfen den „Herdeneffekt“).
🧩 Beispiel: JWT-Validierung und dynamisches Limit
1) Wir validieren den Token direkt in access_by_lua
access_by_lua_block {
local jwt = require "resty.jwt"
local validators = require "resty.jwt-validators"
local auth = ngx.var.http_authorization or ""
local token = auth:match("Bearer%s+(.+)")
if not token then return ngx.exit(ngx.HTTP_UNAUTHORIZED) end
local ok = jwt:verify("shared-secret", token, {
validators.set_system_leeway(60),
validators.require_aud("my-api"),
})
if not ok.valid then return ngx.exit(ngx.HTTP_FORBIDDEN) end
ngx.ctx.user_id = ok.payload.sub
}2) Token-Bucket in Redis über Lua (atomar)
-- KEYS[1]=ключ ведра; ARGV: now(ms), rate(ток/сек), burst
local key = KEYS[1]
local now = tonumber(ARGV[1])
local rate = tonumber(ARGV[2])
local burst= tonumber(ARGV[3])
local data = redis.call("HMGET", key, "tokens", "ts")
local tokens = tonumber(data[1]) or burst
local ts = tonumber(data[2]) or now
local delta = math.max(0, now - ts) / 1000 * rate
tokens = math.min(burst, tokens + delta)
local allowed = tokens >= 1
if allowed then tokens = tokens - 1 end
redis.call("HMSET", key, "tokens", tokens, "ts", now)
redis.call("PEXPIRE", key, math.floor((burst/rate)*1000))
return allowed and 1 or 03) Aufruf von Nginx-Lua
local redis = require "resty.redis"
local r = redis:new()
r:set_timeout(50)
assert(r:connect("redis", 6379))
local key = "tb:" .. (ngx.ctx.user_id or ngx.var.remote_addr) .. ":" .. ngx.var.uri
local allowed = r:eval(token_bucket_script, 1, key, ngx.now()*1000, 5, 10)
r:set_keepalive(1_000, 100) -- пул коннекшенов
if allowed == 0 then return ngx.exit(429) end💡 Die Logik des Limits kann gemischt werden: VIPs erhalten einen größeren burst von Redis.
🧰 Noch mehr Tricks mit Redis+Lua
🔐 API-Idempotenz: Schlüssel des Typs
idem:<hash>mit TTL — wir schneiden Wiederholungen ab.📦 Einzigartige Aufgabenvergabe: Verschieben Sie die Elemente aus dem Satz atomar in die Liste "in Arbeit".
🔒 Leichte Locken:
SET key val NX PX ttl; für verteilte - vorsichtig mit Redlock (bewerten Sie die Risiken des Netzwerks / der Uhr).🧮 Quoten/Limits: Zähler pro Benutzer/Organisation, Reset nach Zeitplan.

📏 Wann der „Rand“ besser ist und wann nicht
Szenario | Lua auf Nginx/Redis | Besser in der App |
|---|---|---|
Routing, Features, Limits | ✅ Sofortige Lösung am Eingang | — |
Schwere Berechnungen, ML, Rendering | ❌ Kein Platz für CPU-Fresser | ✅ Im Backend/Worker |
Atomare Datenoperationen | ✅ Redis Lua — perfekt | — |
Geschäftsregeln und komplexe Transformationen | ⚠️ Möglich, aber vorsichtig | ✅ Lesbarkeit in der Codebasis |
In Kodike Wir machen das Programmierenlernen spannend und verständlich: Wir haben interessante Kurse mit Aufgaben, die helfen, die Fähigkeiten Schritt für Schritt zu verbessern.
Und wir haben auch einen aktiven Telegram-Kanal, wo wir coole Ideen diskutieren, Erfahrungen teilen und Aufgaben gemeinsam analysieren — Lernen wird nicht nur nützlich, sondern auch unterhaltsam.
🧵 Ergebnisse
Lua am „Rand“ bietet sofortige Lösungen: Flags, Limits, Routing, Coalescing.
Redis-Skripte bieten Atomarität und hohe Bandbreite.
Die Hauptsache ist, keine schwere Geschäftslogik auf Nginx zu übertragen. Verwenden Sie es als intelligenten Filter.
Welche Aufgabe würdest du als nächstes an den „Rand“ stellen? Schreiben Sie uns, wir werden es weiter unten analysieren. 💬
