OpenResty 执行阶段介绍
介绍
OpenResty 处理一个请求,它的处理流程请参考下图
图片摘自
说明:
init_by_lua
master init 阶段,初始化全局配置或模块
init_worker_by_lua
workinit 阶段,初始化进程配置
ssl_certificate_by_lua
ssl 设置阶段
ssl_certificate_by_lua_block/ssl_certificate_by_lua_file
当要与客户端 SSL(https)连接握手时,通过上述指令运行 Lua 代码
set_by_lua
流程分支处理判断变量初始化
rewrite_by_lua
转发、重定向、缓存等功能(例如特定请求代理到外网)
access_by_lua
IP 准入、接口权限等情况集中处理(例如配合 iptable 完成简单防火墙)
content_by_lua
内容生成
balancer_by_lua
反向代理选择阶段
header_filter_by_lua
响应头部过滤处理(例如添加头部信息)
body_filter_by_lua
响应体过滤/修改处理(例如完成应答内容统一成大写)
- 通过
ngx.arg[1]
操作发送的数据,ngx.arg[2]
bool 类型,标识是否发送完成
body_filter_by_lua
修改数据后,导致响应体数据长度变化,可以在 header_filter_by_lua
中修改 ngx.header.content_length = nil
删除长度头
log_by_lua
会话完成后本地异步完成日志记录(日志可以记录在本地,还可以同步到其他机器)
- 以下形式可以相互替代
*_by_lua
Lua 代码长度不大于 4KB
*_by_lua_block
*_by_lua_file
content_by_lua_block
content_by_lua_block
用来指定 lua 代码块,以下为 Hello World
的示例:
server {
listen 80;
...
location /hello-world {
default_type text/html;
content_by_lua_block {
ngx.say("Hello World")
}
}
...
OpenResty 中 Lua 变量的范围
全局变量
:init_by_lua*
和 init_worker_by_lua*
阶段定义,尽量少使用,避免污染模块变量
模块变量
:定义在模块里面的变量,不管有没有通过 local
限定,有没有通过 _M
把变量引用起来
模块变量
在每个请求中是共享的
全局变量
能解决的问题,模块变量
也能解决,且更清晰、更干净
Lua VM
会把 require
进来的模块缓存到 package.loaded
表里,除非设置了 lua_code_cache off
,模块里定义的变量都会被缓存起来
ngx.timer.*
里定义的变量都是协程内部的
示例
基本使用
location /phase {
set_by_lua_block $a {
ngx.log(ngx.ERR, "set_by_lua*")
}
rewrite_by_lua_block {
ngx.log(ngx.ERR, "rewrite_by_lua*")
}
access_by_lua_block {
ngx.log(ngx.ERR, "access_by_lua*")
}
content_by_lua_block {
ngx.log(ngx.ERR, "content_by_lua*")
}
header_filter_by_lua_block {
ngx.log(ngx.ERR, "header_filter_by_lua*")
}
body_filter_by_lua_block {
ngx.log(ngx.ERR, "body_filter_by_lua*")
}
log_by_lua_block {
ngx.log(ngx.ERR, "log_by_lua*")
}
}
$ curl -i "http://127.0.0.1/phase"
HTTP/1.1 200 OK
Server: openresty/1.19.9.1
Date: Sun, 22 Jan 2023 11:52:16 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
[error] 8740#0: *1 [lua] set_by_lua:2: set_by_lua*, client: 127.0.0.1, server: localhost, request: "GET /phase HTTP/1.1", host: "127.0.0.1"
[error] 8740#0: *1 [lua] rewrite_by_lua(default.conf:128):2: rewrite_by_lua*, client: 127.0.0.1, server: localhost, request: "GET /phase HTTP/1.1", host: "127.0.0.1"
[error] 8740#0: *1 [lua] access_by_lua(default.conf:131):2: access_by_lua*, client: 127.0.0.1, server: localhost, request: "GET /phase HTTP/1.1", host: "127.0.0.1"
[error] 8740#0: *1 [lua] content_by_lua(default.conf:134):2: content_by_lua*, client: 127.0.0.1, server: localhost, request: "GET /phase HTTP/1.1", host: "127.0.0.1"
[error] 8740#0: *1 [lua] header_filter_by_lua:2: header_filter_by_lua*, client: 127.0.0.1, server: localhost, request: "GET /phase HTTP/1.1", host: "127.0.0.1"
[error] 8740#0: *1 [lua] body_filter_by_lua:2: body_filter_by_lua*, client: 127.0.0.1, server: localhost, request: "GET /phase HTTP/1.1", host: "127.0.0.1"
[error] 8740#0: *1 [lua] log_by_lua(default.conf:143):2: log_by_lua* while logging request, client: 127.0.0.1, server: localhost, request: "GET /phase HTTP/1.1", host: "127.0.0.1"