lua-nginx-module需编译或动态加载启用,非默认模块;通过init_by_lua_block等指令将lua嵌入nginx各处理阶段,支持鉴权、限流、内容生成等;推荐分离逻辑至外部lua文件并用lua_package_path配置路径;注意非阻塞api、共享数据安全及热重载限制。

使用 lua-nginx-module 编写 Nginx 脚本,核心是把 Lua 逻辑嵌入到 Nginx 的请求处理生命周期中,而不是“管理模块”本身——Nginx 模块(包括 lua-nginx-module)需在编译时加载或通过动态模块机制启用,运行时不可增删。Lua 脚本的作用是在已启用该模块的前提下,灵活定制行为。
确认 lua-nginx-module 已正确编译并启用
该模块不是 Nginx 默认内置模块,必须显式编译进 Nginx 或作为动态模块加载:
- 检查是否启用:启动 Nginx 后执行
nginx -V 2>&1 | grep -o with-http_lua_module,有输出说明已编译支持 - 若用动态模块(如 Ubuntu/Debian 官方包可能不带),需在
nginx.conf中添加:
load_module /path/to/ngx_http_lua_module.so; - 确认 LuaJIT 已安装(推荐),或系统 Lua(兼容性较弱)
在配置中嵌入 Lua 代码的常用方式
通过指令将 Lua 片段挂载到不同阶段,每种指令对应特定执行时机:
- init_by_lua_block:Master 进程启动时执行一次(适合初始化全局变量、连接池、加载配置)
- set_by_lua_block:在 rewrite 阶段运行,用于动态设置变量(如生成 token、修改 $arg_xxx)
- access_by_lua_block:在 access 阶段运行(适合鉴权、限流、黑白名单)
- content_by_lua_block:替代 location 内容处理(可完全接管响应,返回 JSON、渲染模板等)
- log_by_lua_block:在日志写入前执行(适合记录自定义字段、上报指标)
示例:简单鉴权
location /api/ {
access_by_lua_block {
local api_key = ngx.var.arg_api_key
if not api_key or api_key ~= "secret123" then
ngx.status = 403
ngx.say("Forbidden")
ngx.exit(403)
end
}
proxy_pass http://backend;
}调用外部 Lua 文件提升可维护性
避免在配置中写大段 Lua,推荐分离逻辑:
- 用 init_by_lua_file / access_by_lua_file 等指令引用文件
- 文件路径为绝对路径,或相对于
nginx.conf所在目录(可用lua_package_path设置搜索路径) - 示例配置:
lua_package_path "/usr/local/nginx/lua/?.lua;;";
access_by_lua_file /usr/local/nginx/lua/auth.lua; -
/usr/local/nginx/lua/auth.lua内容可包含函数、require 其他模块,保持结构清晰
调试与常见注意事项
脚本出错易导致 500 或静默失败,需主动监控和防护:
- 开启 Lua 错误日志:
lua_log_level warn;(默认 error),配合error_log /path/error.log notice; - 避免阻塞操作:不能用
os.execute、io.open(同步读文件)、原生 socket;应使用ngx.socket.tcp()、resty.http等非阻塞 API - 共享数据注意作用域:init 阶段定义的全局 table 可被 worker 共享,但需用
ngx.shared.DICT实现跨 worker 安全存取 - 热重载:修改 Lua 文件后只需
nginx -s reload,无需重启进程(但 init_by_lua* 不会重复执行)











