全书目录

第五十四篇:OpenResty 完全指南 —— 可编程网关锻造厂宇宙

六、插件思维:OpenResty 真正高级的玩法

1 分钟 172 字 第 941 / 962 个阅读单元

如果你继续把逻辑全写在 access_by_lua_block 里,很快就会变成巨型脚本泥球。
正确方向是“插件化”。

#1. 插件链是什么

本质就是:把不同治理能力拆成独立模块,按顺序执行。

text
request
  |
  +--> correlation_id
  +--> auth
  +--> rate_limit
  +--> canary
  +--> audit
  |
proxy to upstream

#2. 一个简单插件调度器

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

接入点:

lua
local ctx = {}
local ok, err = require("gateway.pipeline").run(ctx)
if not ok then
    return ngx.exit(ngx.status)
end

这就是 OpenResty 做网关时最自然的工程化形态:
Nginx 负责请求相位编排,Lua 负责插件流水线编排。