{}const=>[]async()letfn</>var
Développement

Lua sur le « bord » : des astuces inattendues dans Nginx et Redis

Comment transformer Nginx et Redis en points d'automatisation intelligents à l'aide de Lua : indicateurs de fonctionnalités de périphérie, routage intelligent et A/B, buckets de jetons et requêtes de coalescence, micro-WAF et opérations atomiques dans Redis. Quand la logique doit être portée à l'extrême et quand elle doit être laissée dans le backend.

К

Kodik

Auteur

5 min de lecture

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.

🔥 100 000+ étudiants déjà avec nous

Marre de lire la théorie ?
Il est temps de coder !

Kodik — une appli où tu apprends à coder par la pratique. Mentor IA, leçons interactives, projets réels.

🤖 IA 24/7
🎓 Certificats
💰 Gratuit
🚀 Commencer
Ont rejoint aujourd'hui

🌐 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+endpoint ou user_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 0

3) 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. 💬

🎯Arrête de reporter

Tu as aimé l'article ?
Place à la pratique !

Avec Kodik, tu ne lis pas seulement — tu codes immédiatement. Théorie + pratique = vraies compétences.

Pratique instantanée
🧠L'IA explique le code
🏆Certificat

Sans inscription • Sans carte