Imaginez : 02:17, pic nocturne. Un upstream est en train de rendre l'âme, la file d'attente s'allonge, l'analyste demande d'activer une nouvelle fonctionnalité uniquement pour une partie du trafic, et le marketing demande de ne pas perdre la vitesse des pages. La solution n'est pas dans le backend. La solution est à la périphérie : Nginx avec Lua, plus un « bloc-notes d'état » rapide : Redis. En quelques millisecondes, vous activez le drapeau de fonctionnalité, redirigez les requêtes, limitez les clients « bavards » et renvoyez le cache là où il est sûr. ⚡
Lua dans Nginx — c'est un mini-cerveau juste à la porte d'entrée de votre service : il voit les en-têtes, les cookies, les motifs étranges, parle à Redis et prend des décisions petites mais critiques avant que la demande n'atteigne l'application. Redis fournit l'atomicité et la vitesse : compteurs, quotas, drapeaux, idempotence, sans courses et sans transactions lourdes.

🧠 Pourquoi Lua est-il au bord
⚡ Vitesse et E/S non bloquantes: OpenResty/ngx_lua fonctionne dans un modèle événementiel, sans blocage.
🧩 Intégration: les scripts règlent le comportement directement dans les phases Nginx (rewrite/access/header/body/log).
🔒 Atomicité dans Redis : les scripts Lua sont exécutés en une seule opération (pas de course de données).
L'idée clé : « une petite logique à l'entrée » économise les ressources du backend et donne une maniabilité fine.
🌐 Applications inattendues dans Nginx + Lua
🎛️ Edge-feature flags: nous activons les fonctionnalités par segments (pays, version client) avant d'entrer dans l'application.
🧭 Routage intelligent: nous acheminons le trafic selon les plans d'abonnement/options AB, nous lisons les règles de Redis.
🛡️ Micro-WAF: blocages « souples » basés sur des signatures comportementales, sans interférer avec les utilisateurs légaux.
🧯 Disjoncteur à l'entrée: couper temporairement le flux ascendant malade, donner un cache/une fiche.
🧹 Normalisation des URL: canonisation, compression des requêtes indésirables, lutte contre les doublons pour le cache.
🔗 Comment cela est lié à Redis
🏷️ Drapeaux/règles vivent dans Redis avec TTL → propagation instantanée sans redémarrage de Nginx.
🧪 A/B: l'option de l'utilisateur est stockée dans Redis → cohérence entre les requêtes.
🚦 Rate limiting: seaux à jetons/seaux à clés
IP+endpointouuser_id.🔁 Request coalescing: une demande au back-end, les autres attendent (nous étouffons « l'effet de troupeau »).
🧩 Exemple : validation JWT et limite dynamique
1) Validez le jeton directement dans 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) Seau à jetons dans Redis via Lua (atomique)
-- 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) Appel depuis 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💡 La logique de la limite peut être mélangée : les VIP obtiennent un plus grand burst de Redis.
🧰 Plus de trucs avec Redis+Lua
🔐 Idempotence de l'API: clé de type
idem:<hash>avec TTL — on coupe les répétitions.📦 Distribution unique des tâches: déplacer atomiquement les éléments de l'ensemble dans la liste « en cours ».
🔒 Boucles légères:
SET key val NX PX ttl; pour les systèmes distribués, soyez prudent avec Redlock (évaluez les risques du réseau/des montres).🧮 Quotas/limites: compteurs par utilisateur/organisation, réinitialisation planifiée.

📏 Quand le « bord » est meilleur et quand il ne l'est pas
Scénario | Lua sur Nginx/Redis | Mieux dans l'application |
|---|---|---|
Itinéraire, fonctionnalités, limites | ✅ Solution instantanée à l'entrée | — |
Calculs lourds, ML, rendu | ❌ Pas un endroit pour les gourmands de CPU | ✅ Dans le backend/worker |
Opérations atomiques de données | ✅ Redis Lua — idéal | — |
Règles commerciales et transformations complexes | ⚠️ C'est possible, mais avec précaution | ✅ Lisibilité dans la base de code |
Dans Codique nous rendons l'apprentissage de la programmation passionnant et compréhensible : nous avons des cours intéressants avec des tâches qui aident à améliorer les compétences étape par étape.
Et nous avons aussi un chaîne de télégram, où nous discutons d'idées intéressantes, partageons nos expériences et analysons ensemble les tâches, apprendre devient non seulement utile, mais aussi amusant.
🧵 Résultats
Lua sur le « bord » fournit des solutions instantanées : drapeaux, limites, routage, coalescence.
Les scripts Redis assurent l'atomicité et un débit élevé.
L'essentiel est de ne pas transférer une logique métier lourde vers Nginx ; utilisez-le comme un filtre intelligent.
Quelle tâche placeriez-vous en « bordure » de la suivante ? Écrivez, nous l'analyserons dans la suite. 💬
