{}const=>[]async()letfn</>var
開発

Luaの「エッジ」:NginxとRedisの予期しないトリック

Luaを使用してNginxとRedisをスマートな自動化ポイントに変える方法:エッジ機能フラグ、スマートルーティングとA/B、トークンバケットとクエリの結合、マイクロWAFとRedisでの原子操作。ロジックをエッジに移すべき時と、バックエンドに残すべき時。

К

Kodik

著者

2分で読める

想像してみてください。 02:17、夜のピークアップストリームが1つ死にかけています。キューは長くなっています。アナリティクスはトラフィックの一部に対してのみ新機能を有効にするよう求めています。マーケティングはページの速度を落とさないようにしています。ソリューションはバックエンドではありません。解決策は「エッジ」にあります。NginxとLua、さらに高速な「状態ノートブック」Redisです。ミリ秒単位でフィーチャーフラグをオンにし、リクエストをリダイレクトし、「おしゃべりな」クライアントを制限し、安全な場所にキャッシュを返します。⚡

NginxのLua — これは、サービスの入り口にあるミニブレインです。ヘッダー、Cookie、奇妙なパターンを見て、Redisと話し、リクエストがアプリケーションに到達する前に小さな、しかし重要な決定を下します。Redisは、カウンター、クォータ、フラグ、イデムポテンシーなど、競争や重いトランザクションなしで、アトミック性と速度を提供します。

🧠なぜLuaが限界にいるのか

  • 速度とノンブロッキングI/O: OpenResty / ngx_luaは、ロックなしでイベントモデルで動作します。

  • 🧩 埋め込み:スクリプトは Nginx フェーズ(書き換え/アクセス/ヘッダー/本文/ログ)で動作を直接制御します。

  • 🔒 原子性 Redis: Lua スクリプトは単一の操作として実行されます(データ競合はありません)。

重要な考え方:「入力時の小さなロジック」はバックエンドのリソースを節約し、細かい制御を可能にします。

🔥 10万人以上の学生が参加中

理論を読むのに疲れた?
コーディングの時間だ!

Kodik — 実践でプログラミングを学ぶアプリ。AIメンター、インタラクティブなレッスン、実際のプロジェクト。

🤖 AI 24時間
🎓 修了証
💰 無料
🚀 始める
今日参加

🌐 Nginx + Luaでの予期しない使用

  • 🎛️ Edge-feature flags:アプリケーションにアクセスする前に、セグメント(国、クライアントのバージョン)ごとに機能を有効にします。

  • 🧭 スマートルーティング:加入者プラン/ABバリアントにトラフィックを送信し、Redisからルールを読み取ります。

  • 🛡️ マイクロWAF: 正規ユーザーを妨害することなく、行動シグネチャに基づいて「ソフト」ブロックを実行します。

  • 🧯 入力側の回路ブレーカー:一時的に患者のアップストリームを切断し、キャッシュ/プラグを提供します。

  • 🧹 URL の正規化:正規化、ガベージクエリの圧縮、キャッシュの重複との戦い。

🔗 Redisとの関連性

  • 🏷️ フラグ/ルール TTL で Redis に存在 → Nginx を再起動せずに瞬時に配布されます。

  • 🧪 A/B:ユーザーの選択肢はRedisに保存されます→クエリ間の一貫性。

  • 🚦 Rate limiting:トークンバケット/キーの注ぎ口IP+endpoint または user_id

  • 🔁 Request coalescing:バックに1つのリクエストを送り、残りは待機します(「群れ効果」を抑制します)。

🧩例: JWT検証と動的制限

1)トークンを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)Luaを介したRedisのトークンバケット(原子)

-- 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)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

💡制限のロジックは混合できます。VIPはRedisからより大きなburstを受け取ります。

🧰 Redis + Luaのその他のトリック

  • 🔐 API のイデムポテンシー:TTLを持つidem:<hash>タイプのキー—繰り返しを切り捨てます。

  • 📦 ユニークなタスクの割り当て:セットから「作業中」リストに要素を原子的に移動します。

  • 🔒 軽いカールSET key val NX PX ttl;分散型の場合は、Redlockを使用して慎重に(ネットワーク/時計のリスクを評価します)。

  • 🧮 割り当て/制限:ユーザー/組織ごとのカウンター、スケジュールによるリセット。

📏「端」が良い場合とそうでない場合

シナリオ

Nginx/Redis での Lua

アプリでより良い

ルーティング、機能、制限

✅ 入口での即時解決

重い計算、ML、レンダリング

❌ CPU を大量に消費するものには向いていません

✅ バックエンド/ワーカー

原子データ操作

✅ Redis Lua — 完璧

ビジネスルールと複雑な変換

⚠️ 可能ですが、注意が必要です

✅コードベースの可読性

B コディケ 私たちはプログラミングの学習を楽しくわかりやすくします。ステップバイステップでスキルを磨くのに役立つ課題を伴う興味深いコースを用意しています。

また、アクティブな テレグラムチャンネル、ここでは素晴らしいアイデアについて話し合い、経験を共有し、課題を一緒に分析します。学習は有益であるだけでなく、楽しいものになります。

🧵 結果

  • Luaは「エッジ」で即座に解決策を提供します。フラグ、制限、ルーティング、コアリングなどです。

  • Redis スクリプトは、原子性と高いスループットを提供します。

  • 重要なのは、重いビジネスロジックをNginxに移行しないことです。スマートフィルターとして使用してください。

次の「端」にどんなタスクを置きますか?書いてください、続きで分析します。 💬

🎯先延ばしをやめよう

記事は気に入った?
実践の時間だ!

Kodikでは読むだけでなく、すぐにコードを書く。理論 + 実践 = 本当のスキル。

即座に実践
🧠AIがコードを説明
🏆修了証

登録不要 • カード不要