一、Nginx Lua API 的两个标准库: ngx 和 ndk
1. 在 nginx.conf 文件中,所有的 *_by_lua, *_by_lua_block 和 _by_lua_file 都被看做是一个通向 Lua API 的入口。Nginx Lua API 中的函数只能在上述配置指令中(_by_lua, *_by_lua_block 和 *_by_lua_file)运行。
2. Nginx Lua API 通过向 Lua 提供 ngx 和 ndk 两个标准库来实现 Lua 对 Nginx Lua API 的调用。这两个标准库一般情况下,在上述配置指令中(*_by_lua, *_by_lua_block 和 *_by_lua_file)总是可用的,也可以将这两个标准库集成到任意的Lua模块中。也可用在外部 Lua 模块中,使用 local ngx = require "ngx" 和 local ndk = require "ndk" 来手动引入
二、总是在 Lua 代码中使用 Nginx Lua API 来完成网络请求和磁盘IO
1. 使用 Nginx Lua API 来完成网络请求,否则 Nginx 的事件轮询将被阻塞,导致性能急剧下降。
2. 小量的磁盘IO可用使用 Lua 自身的IO库来完成,但应该尽量避免对大文件的读和写导致Nginx进程阻塞。
3. 将网络请求和磁盘IO委托给Nginx的子请求将明显提高nginx性能。
三、ngx.var
1. 可用通过 value = ngx.var.*** 来获取变量,通过 ngx.var.*** = 123 来设置变量的值。但 ngx.var 的变量只能先声明后使用。
2. 一些系统变量,如:http_NAME,只是可读的。
3. 可用通过 ngx.var[1], ngx.var[2] .. 来获取正则表达式的 2
4. 手动将 ngx.var.*** = nil 设置为空,将会删除这个变量
5. 每次读 ngx.var.*** 变量时,nginx会在只读一次的内存块中分配一块内存来保存这个变量,并且在读操作完成后,销毁它。因此,在反复读某个 ngx.var.*** 变量时,最好先将变量保存到 lua 变量中。同时,如果为了避免在同一次请求过程中的临时内存泄露,也可以将 ngx.var.*** 保存到 ngx.ctx 中。
6. 未声明的 ngx.var.*** 变量默认是 nil,在 lua 中是 "" 空字符串。尽量避免对未申明的变量的使用,因为比较耗性能。
四、常量
1. Core Constants
- ngx.OK: 0
- ngx.ERROR: -1
- ngx.AGAIN: -2
- ngx.DONE: -4
- ngx.DECLINED: -5
- ngx.null
2. HTTP Method Constants 作为 ngx.location.capture 和 ngx.location.capture_multi 的参数
- ngx.HTTP_GET
- ngx.HTTP_HEAD
- ngx.HTTP_PUT
- ngx.HTTP_POST
- ngx.HTTP_DELETE
- ngx.HTTP_OPTIONS
- ngx.HTTP_MKCOL
- ngx.HTTP_COPY
- ngx.HTTP_MOVE
- ngx.HTTP_PROPFIND
- ngx.HTTP_PROPPATCH
- ngx.HTTP_LOCK
- ngx.HTTP_UNLOCK
- ngx.HTTP_PATCH
- ngx.HTTP_TRACE
3. HTTP Status Constants
4. Nginx 日志等级常量
- ngx.STDERR
- ngx.EMERG
- ngx.ALERT
- ngx.CRIT
- ngx.ERR
- ngx.WARN
- ngx.NOTICE
- ngx.INFO
- ngx.DEBUG
五、print 函数
print 函数用于:以 nginx.NOTICE 级别向 error.log 文件写入日志,等同与: ngx.log(ngx.NOTICE, ...)
六、ngx.ctx 上下文数组
1. ngx.ctx 是一个 table,它的生命周期和本次请求的生命周期一样,可以存储一些本次请求过程中的数据。
2. 每一个请求,包含子请求,都有各自独立的 ngx.ctx 互不干扰。即:主请求的 ngx.ctx.var_ctx 和 ngx.location.capture() 出来的子请求中的 ngx.ctx.var_ctx 互不干扰。
3. 主请求中的 ngx.ctx 数据并不延续到内部重定向的请求中。即:在主请求中设置 ngx.ctx.var_master=value,然后 ngx.exec() 后,内部重定向的请求中,local var_master=ngx.ctx.var_master 将为 nil。
4. 可以使用 lua table 对 ngx.ctx 进行初始化,如: ngx.ctx = {a=1,b=2}。如果在 init_worker_by_lua 中这样做,将使其在整个请求的 Lua 处理过程中都有效。
5. 相比在每次请求中传递自定义函数参数和使用 ngx.ctx,ngx.ctx 中查询相当耗费性能,滥用 ngx.ctx 将对性能产生很大影响。
七、ngx.location.capture
1. res = ngx.location.capture(uri, options?),产生一个指定uri的同步并非阻塞的子请求
2. 子请求模仿了 http 请求,但并不会进行 HTTP/TCP 通信,它只是在 C 语言层面上工作。子请求和 ngx.redirect 和 ngx.exec 完全不同。子请求的返回值将保存在内存中,对于庞大的返回值,需要流式处理。
3. ngx.location.capture 的返回值对象 res 有4个键值:
- res.status, 保存了子请求的状态码
- res.header, 按返回顺序,以二位数组的方式,保存的返回的头信息
- res.body, 保存了子请求的返回内容,可能会由于内容过长被截断。数据被截断的原因是子请求中出现了一些解决不了的错误,比如:在返回数据的过程中,子请求提前断开了链接,或者子请求在请求其他服务时遭遇了超时。
- res.truncated, 表明子请求是否被截断。
4.ngx.location.capture 可选参数 table:
- method:指定子请求的请求方法。默认 ngx.HTTP_GET
- body:字符串类型的请求体
- args:URI 查询参数
- ctx:指定子请求使用的上下文环境。在当前轻轻中,使用变量作为子请求的 ctx 时,若子请求通过 ngx.ctx.***=aaa 修改了 ctx,修改将作用到当前请求被传递至 ctx 作为子请求上下文环境的变量。
- vars:指定子请求的 ngx.var
- copy_all_vars:是否复制当前请求的 ngx.var 变量到子请求中(子请求对变量的修改并不会影响到当前请求)
- share_all_vars:是否在当前请求和子请求间共享 ngx.var 变量(子请求对变量的修改将影响到当前请求)。开启本参数将使调试等变得很困难,慎重开启。默认 false。与 copy_all_vars 同时使用时,share_all_vars 优先生效。与 copy_all_vars 和 vars 同时使用时,vars 优先生效。
- always_forward_body:是否将当前请求的请求体作为子请求的请求体