如果你继续把逻辑全写在 access_by_lua_block 里,很快就会变成巨型脚本泥球。
正确方向是“插件化”。
#1. 插件链是什么
本质就是:把不同治理能力拆成独立模块,按顺序执行。
request
|
+--> correlation_id
+--> auth
+--> rate_limit
+--> canary
+--> audit
|
proxy to upstream#2. 一个简单插件调度器
-- lua/gateway/pipeline.lua
local plugins = {
require("plugins.correlation_id"),
require("plugins.auth"),
require("plugins.canary"),
}
local _M = {}
function _M.run(ctx)
for _, plugin in ipairs(plugins) do
local ok, err = plugin.run(ctx)
if ok == false then
return nil, err
end
end
return true
end
return _M-- lua/plugins/correlation_id.lua
local _M = {}
function _M.run(ctx)
local rid = ngx.var.request_id
ngx.req.set_header("X-Request-Id", rid)
ctx.request_id = rid
return true
end
return _M-- lua/plugins/auth.lua
local _M = {}
function _M.run(ctx)
local auth = ngx.req.get_headers()["authorization"]
if auth ~= "Bearer demo-token" then
ngx.status = 401
ngx.say('{"error":"unauthorized"}')
return false, "unauthorized"
end
ctx.user = "demo"
return true
end
return _M-- lua/plugins/canary.lua
local _M = {}
function _M.run(ctx)
local h = ngx.req.get_headers()["x-canary"]
if h == "1" then
ngx.var.target_upstream = "backend_canary"
end
return true
end
return _M接入点:
local ctx = {}
local ok, err = require("gateway.pipeline").run(ctx)
if not ok then
return ngx.exit(ngx.status)
end这就是 OpenResty 做网关时最自然的工程化形态:
Nginx 负责请求相位编排,Lua 负责插件流水线编排。