Nginx Lua API 学习

一、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
image.png
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:是否将当前请求的请求体作为子请求的请求体
5. 子请求默认使用和当前请求一样的请求头信息
6. POST 和 PUT 类型的子请求,当未设置 body 参数且 always_forward_body=false 时,子请求将继承当前请求的 body 信息
7. 在 1.1.x 版本之前,一个请求最多可以有 50 个子请求,在 1.1.x 之后的版本,一个请求最多可以有 200 个子请求。可以修改 nginx/src/http/ngx_http_request.h 中的 NGX_HTTP_MAX_SUBREQUESTS 来修改这个限制

八、ngx.location.capture_multi

1. res1, res2, ... = ngx.location.capture_multi({ {uri, options?}, {uri, options?}, ... }), 并行地发出多个子请求,且返回顺序和发出顺序一致。
2. 直到所有的子请求都返回后,才会返回。且总延迟依赖与子请求中最大的延迟。
3. 当子请求数量不确定时,可以 local resps = { ngx.location.capture_multi(reqs) } 的方式对结果进行 for i, resp in ipairs(resps) do 处理。

九、ngx.status

1. 可以在当前请求输出响应头信息之前,查看或者设置当前请求的返回状态码。在输入响应头信息之后设置 ngx.status 没有任何意义且会报错。
2. ngx.status = ngx.HTTP_CREATED,设置当前请求的响应状态码
3. status = ngx.status,查看当前请求的响应状态码

十、ngx.header.*** 查看或设置当前请求的返回头信息

1. ngx.header.*** = VALUE,设置返回头信息
2. value = ngx.header.***,查看返回头信息
3. 默认情况下,头信息下的 _ 将被替换成 -,即:content_type 会被改写成 content-type,可以用过关闭 lua_transform_underscores_in_response_headers 来禁用此功能。响应头信息是大小写敏感的。
4. ngx.header["***"] = nil,将删除之前设定的 *** 返回头信息。
5. 在发送响应头之后,无论使用 ngx.send_headers 或者 ngx.header.*** = VALUE 都将产生错误,并记录到 error.log 中。
6. ngx.header 并不是一个常规的 Lua table,不能使用 ipairs 来遍历它。但可以使用 ngx.req.get_headers 来获取一个可遍历的常规 Lua table、

十一、ngx.reps.get_headers 和 ngx.req.get_headers

1. headers = ngx.resp.get_headers(max_headers?, raw?),返回一个包含当前请求所有响应头信息的常规 Lua table。
2. headers = ngx.req.get_headers(),返回一个包含当前请求所有请求头信息的常规 Lua table。

你可能感兴趣的:(Nginx Lua API 学习)