OpenResty 中 lua 脚本的使用
OpenResty 用 lua-nginx-module 解释 lua 脚本,lua 语言自身的用法见 Lua编程速查手册(常用操作),openresty 提供的 lua 能力(譬如定义的变量、提供的函数等)见 openresty/lua-nginx-module 。
OpenResty 执行 Lua 脚本
OpenResty 支持的开发语言是 lua,lua 脚本可以用两种方式运行:
第一种方式,直接写在配置文件中,openresty 加载运行:
$ cd 01-hello-world
$ openresty -p `pwd` -c nginx.conf
这种方式启动了 openresty 服务,访问 openresty 时触发配置中的 lua 脚本的运行:
$ curl 127.0.0.1:6699/
HelloWorld
第二种方式,用 resty 命令直接执行 lua 脚本:
$ cd 02-hello-world
$ resty hello.lua
hello world
lua_module 的几个执行阶段
lua_module 定义了很多的指令,lua module directives,其中有一些指令是类似于 server、location 的块指令,它们的作用顺序如下:
用下面的配置观察这些指令的执行顺序,03-nginx-lua-module/nginx.conf:
worker_processes 1; #nginx worker 数量
error_log logs/error.log info; #指定错误日志文件路径
events {
worker_connections 256;
}
http {
server {
#监听端口,若你的6699端口已经被占用,则需要修改
listen 6699;
location / {
set_by_lua_block $a {
ngx.log(ngx.INFO, "set_by_lua*")
}
rewrite_by_lua_block {
ngx.log(ngx.INFO, "rewrite_by_lua*")
}
access_by_lua_block {
ngx.log(ngx.INFO, "access_by_lua*")
}
content_by_lua_block {
ngx.log(ngx.INFO, "content_by_lua*")
}
header_filter_by_lua_block {
ngx.log(ngx.INFO, "header_filter_by_lua*")
}
body_filter_by_lua_block {
ngx.log(ngx.INFO, "body_filter_by_lua*")
}
log_by_lua_block {
ngx.log(ngx.INFO, "log_by_lua*")
}
}
}
}
执行时打印的日志:
2019/10/23 15:40:34 [info] 65194#3586531: *1 [lua] set_by_lua:2: set_by_lua*, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:6699"
2019/10/23 15:40:34 [info] 65194#3586531: *1 [lua] rewrite_by_lua(nginx.conf:17):2: rewrite_by_lua*, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:6699"
2019/10/23 15:40:34 [info] 65194#3586531: *1 [lua] access_by_lua(nginx.conf:20):2: access_by_lua*, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:6699"
2019/10/23 15:40:34 [info] 65194#3586531: *1 [lua] content_by_lua(nginx.conf:23):2: content_by_lua*, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:6699"
2019/10/23 15:40:34 [info] 65194#3586531: *1 [lua] header_filter_by_lua:2: header_filter_by_lua*, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:6699"
2019/10/23 15:40:34 [info] 65194#3586531: *1 [lua] body_filter_by_lua:2: body_filter_by_lua*, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:6699"
2019/10/23 15:40:34 [info] 65194#3586531: *1 [lua] log_by_lua(nginx.conf:32):2: log_by_lua* while logging request, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:6699"
2019/10/23 15:40:34 [info] 65194#3586531: *1 kevent() reported that client 127.0.0.1 closed keepalive connection
与 nginx 内置变量的交互
nginx 有很多 内置变量,在 lua 脚本中通过 ngx.var.VARIABLE 获取这些变量。
有一些 nginx 的变量值可以用 lua 修改,大部分是不可以修改的。
修改不能修改的变量时会报错,例如:
lua entry thread aborted: runtime error: ... variable "request_uri" not changeable
与 nginx 共享内存的交互
ngx.shared.DICT 获取用 ua_shared_dict 创建的共享内存。
当前请求的上下文
ngx.ctx 中存放当前请求的上下文,贯穿所有处理阶段:
location /test {
rewrite_by_lua_block {
ngx.ctx.foo = 76
}
access_by_lua_block {
ngx.ctx.foo = ngx.ctx.foo + 3
}
content_by_lua_block {
ngx.say(ngx.ctx.foo)
}
}