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 做善后。