Nginx Lua Lifecycle
1. Nginx 进程生命周期
Nginx 启动 → Master 进程 → Fork Worker → Worker 处理请求 → Worker 退出 → Master 退出。
在这个过程中,Lua 脚本可能运行在 配置阶段、进程启动阶段、请求处理阶段、定时器/异步阶段。
2. Lua 执行生命周期阶段
(1) 配置阶段
init_by_lua/init_by_lua_file发生在 master 进程加载配置时(
nginx -s reload也会触发)全局只执行一次,适合初始化全局 Lua 环境、加载模块、预热缓存等
注意:此时不能用
ngx.*请求相关 API(因为没有请求上下文)
(2) Worker 初始化阶段
init_worker_by_lua/init_worker_by_lua_file每个 worker 进程启动时执行一次。
用来启动定时器(
ngx.timer.at)、初始化 worker 级别状态同样不能用请求相关的 API,但可以用 cosocket API 连接数据库、Redis 等。
(3) 请求处理阶段(核心生命周期)
当请求进入 worker 时,Lua 脚本可挂在不同阶段:
set_by_lua执行在 rewrite 阶段之前,用于设置变量。
要求必须返回值,执行环境有限制。
rewrite_by_lua在 rewrite 阶段运行,可改写 URI、做路由逻辑。
可以使用大部分
ngx.*API。
access_by_lua在 access 阶段运行,可做鉴权、限流
若调用
ngx.exit(403)等可中止请求。
content_by_lua生成响应的主要阶段。
可以写响应体、调用上游接口、反向代理等。
最完整的请求上下文。
header_filter_by_lua在返回响应头时执行,可以修改响应头。
无法再写响应体。
body_filter_by_lua在发送响应体时执行,可以修改响应体(比如做压缩/替换)。
数据是流式的,可能分多次调用。
log_by_lua在请求完成后执行(log 阶段),适合写日志、打点。
不影响请求结果,但仍有请求上下文。
(4) 请求外的异步生命周期
Timer 回调 (
ngx.timer.at)在 worker 内调度执行,独立于请求上下文。
可用于周期任务,如心跳、定时清理。
Light thread (coroutine)
ngx.thread.spawn启动的“轻线程”,和请求生命周期绑定,请求结束后会被杀掉。
Cosocket API (
ngx.socket.tcp,ngx.req.socket)支持非阻塞 IO,生命周期跟随请求(除非在定时器里)。
(5) Worker/进程退出阶段
没有专门的 exit_worker_by_lua 钩子
Worker 退出时不会显式调用 Lua 脚本。
如果需要清理,可以靠定时器或 log_by_lua 做善后。