nginx http执行阶段
# ngx_http_core_module.h
typedef enum {
NGX_HTTP_POST_READ_PHASE = 0,
NGX_HTTP_SERVER_REWRITE_PHASE,
NGX_HTTP_FIND_CONFIG_PHASE,
NGX_HTTP_REWRITE_PHASE,
NGX_HTTP_POST_REWRITE_PHASE,
NGX_HTTP_PREACCESS_PHASE,
NGX_HTTP_ACCESS_PHASE,
NGX_HTTP_POST_ACCESS_PHASE,
NGX_HTTP_PRECONTENT_PHASE,
NGX_HTTP_CONTENT_PHASE,
NGX_HTTP_LOG_PHASE
} ngx_http_phases;
执行阶段说明
NGX_HTTP_POST_READ_PHASE = 0,
* 接受并读取请求
NGX_HTTP_SERVER_REWRITE_PHASE,
* 修改url阶段,通常有重定向、变量设置
NGX_HTTP_FIND_CONFIG_PHASE,
* 查找url对应的配置,如匹配location
NGX_HTTP_REWRITE_PHASE,
* 匹配到location后,可能会再次进入NGX_HTTP_SERVER_REWRITE_PHASE
NGX_HTTP_POST_REWRITE_PHASE,
* 检查url是否执行过阶段4,如果执行了,再次进入阶段3
* 最大检查次数为10,超过会报错
NGX_HTTP_PREACCESS_PHASE,
* 请求资源限速等操作
NGX_HTTP_ACCESS_PHASE,
* 访问控制,如限制ip访问
NGX_HTTP_POST_ACCESS_PHASE,
* 验证NGX_HTTP_ACCESS_PHASE(访问控制)结果,如果通过则继续
NGX_HTTP_PRECONTENT_PHASE,
* try_files指令时生效
NGX_HTTP_CONTENT_PHASE,
* 处理http请求内容,一般需要与后端应用进行交互
NGX_HTTP_LOG_PHASE
* 日志输出
执行顺序
init_by_lua_block
init_worker_by_lua_block
set_by_lua_block
rewrite_by_lua_block
access_by_lua_block
content_by_lua_block
header_filter_by_lua_block
body_filter_by_lua_block
log_filter_by_lua_block
init_by_lua_block:nginx初始化、重启时执行,在http模块中设置
http {
include mime.types;
default_type application/octet-stream;
init_by_lua_block {
local uuid = require 'resty.jit-uuid';
uuid.seed();
}
...
}
init_by_lua_file:作用与init_by_lua_block相同,代码块保存在文件中
http {
include mime.types;
default_type application/octet-stream;
init_worker_by_lua_file /usr/local/nginx/conf/init.lua
...
}
# /usr/local/nginx/conf/init.lua 文件内容
local uuid = require 'resty.jit-uuid';
uuid.seed();
init_worker_by_lua_block:master进程启动后,执行相关代码块,在http模块中设置
# 可用来执行定时任务、后端健康检查
http {
include mime.types;
default_type application/octet-stream;
init_worker_by_lua_block {
...
}
...
}
set_by_lua_block:执行代码块,并将结果返回,在server、location语句块中设置
语法格式:set_by_lua_block $result {...}
* 该命令是阻塞命令,执行的语句块尽可能短、快,避免耗时过多
* 语句块中禁用:ngx.say()、ngx.exit()、ngx.sleep()等命令
server {
listen 80;
server_name localhost;
set $a "";
set_by_lua_block $a {
return "1";
}
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
...
}
rewrite_by_lua_block:重写阶段执行,可在http、server、location中设置
语法格式:rewrite_by_lua_block {...}
* 语句块会在最后执行,可通过rewrite_by_lua_no_postpone(默认off)改变执行顺序
* 可调用所有ngx api
# a的值为2
server {
listen 80;
server_name localhost;
set $a "1";
rewrite_by_lua_block {
ngx_var_a="2";
}
set $a "3"
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
...
}
# http阶段配置:rewrite_by_lua_no_postpone on
# a的值为3
server {
listen 80;
server_name localhost;
set $a "1";
rewrite_by_lua_block {
ngx_var_a="2";
}
set $a "3"
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
...
}
access_by_lua_block:access阶段执行语句块(权限检查、黑白名单),在http、server、location中设置
语法格式:access_by_lua_block {...}
* 语句块会在最后执行,可通过access_by_lua_no_postpone(默认off)改变执行顺序
* 可调用所有ngx api
* 应用:将黑白名单存放在redis、共享内存中,动态设置黑白名单
content_by_lua_block:内容处理阶段执行,设置输出内容,在location中设置
语法格式:content_by_lua_block {...}
* 可调用所有ngx api
* 若与其他内容执行阶段语句同时使用,content_by_lua_block可能不会执行
location / {
content_by_lua_block {
ngx.say("hello gtlx");
}
echo "test" #只会输出test,不会输出hello gtlx
}
content_by_lua_file:与content_by_lua_block相同,语句保存在文件中,在location中设置
语法格式:content_by_lua_file file
* 可调用所有ngx api
location / {
content_by_lua_file /usr/local/openresty/file/test.lua
}
# 文件:/usr/local/openresty/file/test.lua
hello gtlx
balancer_by_lua_block:内容处理阶段执行,在upstream语句中使用
语法格式:balancer_by_lua_block {...}
* upstream使用的ip为balancer_by_lua_block中设置的地址
* 禁用的api:cosockets、light threads
upstream web-server {
server 172.18.0.2 #会忽略server设置的ip地址
balancer_by_lua_block {
... #真是使用的ip地址
}
}
header_filter_by_lua_block:响应阶段添加、删除响应头,在http、server、location中设置
语法格式:header_filter_by_lua_block {...}
* 禁用的api:ngx.say()、ngx.redirect()、ngx.exec()等
# 添加响应头
location / {
header_filter_by_lua_block {
ngx.header.test="hello gtlx"
}
echo "hello"
}
body_filter_by_lua_block:响应阶段修改响应体,在http、server、location中设置
语法格式:body_filter_by_lua_block {...}
* 禁用的api:ngx.say()、ngx.redirect()、ngx.exec()等
# 将相应数据转换为大写(ngx.arg[1]获取响应数据,ngx.arg[2]响应结束符)
# 输出:HELLO
location / {
body_filter_by_lua_block {
ngx.arg[1] = string.upper(ngx.arg[1]);
}
echo "hello"
}
log_by_lua_block:输出日志,可在http、server、location中设置
语法格式:log_filter_by_lua_block {...}
* 在access_log之前执行,不会替换当前的access_log日志
* 禁用的api:ngx.say()、ngx.redirect()、ngx.exec()等
location / {
log_filter_by_lua_block {
ngx.log("hello gtlx")
}
echo "hello"
}