Nginx需通过OpenResty或ngx_lua模块支持Lua;常用指令包括init_by_lua_block、set_by_lua_block、access_by_lua_block等,用于不同请求阶段;注意进程隔离、避免阻塞、模块化设计与共享字典使用。

Nginx 本身不原生支持 Lua,需通过 OpenResty(基于 Nginx + LuaJIT 的发行版)或 ngx_lua 模块 来嵌入 Lua 脚本逻辑。直接在官方 Nginx 中启用 Lua 会失败——必须确认环境已正确安装并编译了 ngx_lua 模块。
确认环境支持 Lua
运行以下命令检查是否加载了 ngx_lua 模块:
nginx -V 2>&1 | grep -o with-http_lua_module
若无输出,说明未编译该模块。推荐使用 OpenResty(自带完整 Lua 支持),下载地址:https://www.php.cn/link/0d046bfbcea5badab201f3b708d12b3a。安装后,nginx 命令实际指向 OpenResty 的可执行文件。
在 nginx.conf 中嵌入 Lua 的常用方式
ngx_lua 提供多个指令,将 Lua 代码嵌入不同请求阶段:
- init_by_lua_block:Nginx 启动时执行一次(适合初始化全局变量、连接池、配置加载)
- set_by_lua_block:在 rewrite 阶段运行,用于动态设置变量值(返回字符串,可用于 if 或 proxy_pass)
- access_by_lua_block:在 access 阶段运行(适合权限校验、限流、黑白名单)
- content_by_lua_block:替代 location 内容处理(如直接返回 JSON、渲染页面,跳过静态文件服务)
- header_filter_by_lua_block:修改响应头(如添加自定义 Header)
- body_filter_by_lua_block:过滤响应体(流式处理,慎用)
示例:在 server 块中添加一个简单鉴权逻辑:
location /api/ {
access_by_lua_block {
local token = ngx.var.arg_token
if not token or token ~= "secret123" then
ngx.status = 403
ngx.say("Forbidden")
ngx.exit(403)
end
}
proxy_pass http://backend;
}
注意事项与常见问题
Lua 脚本在 Nginx 多进程模型中运行,需注意:
- 每个 worker 进程独立执行 init_by_lua_block,全局变量不跨进程共享
- 避免在 Lua 中做阻塞操作(如同步 HTTP 请求、文件读写),应使用 cosocket(
resty.http)异步调用 - 敏感逻辑建议抽离到外部服务,Nginx Lua 层只做轻量判断
- 调试时开启
error_log /path/to/error.log debug;,Lua 错误会输出到 error log(需编译时启用 --with-debug) - 脚本内不要用
print(),改用ngx.log(ngx.INFO, "msg")
推荐项目结构与进阶实践
生产环境不建议把大量 Lua 逻辑硬编码在 nginx.conf 中:
- 使用
lua_package_path设置 Lua 模块搜索路径,例如:
lua_package_path "/usr/local/openresty/lualib/?.lua;/path/to/mylib/?.lua;;"; - 将业务逻辑拆分为 Lua 模块(如
auth.lua、rate_limit.lua),在配置中 require 使用 - 结合
lua_shared_dict创建共享内存字典,实现跨请求计数(如限流计数器) - 使用
resty.session或 JWT 库管理会话,避免依赖 Cookie+后端存储
不复杂但容易忽略。关键在选对阶段、避开阻塞、善用共享字典和模块化设计。










