摘自:http://www.daileinote.com/computer/openresty/05
下面是 lua-nginx-module 模块的一些配置指令
lua_package_path
1 | syntax: lua_package_path <lua-style-path-str> |
设置 lua 模块的搜索路径,可以包含 $prefix 或 ${prefix} 变量,当我们有多个 openresty 程序通过 -p 命令指定工作目录启动时非常有用。
lua_package_cpath
1 | syntax: lua_package_cpath <lua-style-path-str> |
指定c动态库搜索路径,其他的同上。
1 | lua_package_cpath '/usr/lib64/lua/5.1/?.so;;/tmp/lua/*.so;;'; |
init_by_lua_block
1 | context: http |
启动nginx时,在每个 worker 进程 fork() 之前调用,如果关闭了 lua_code_cache,那么每次请求都会调用。一般用来预先加载常用的 lua 库。
由于是在 worker fork()调用之前,数据和代码在这里加载会省内存,基于操作系统 "写时拷贝" 特性。
在这里也可以初始化共享内存。
目前只支持 ngx.log、print、ngx.shared.DICT API。
init_by_lua_file
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算。
1 | init_by_lua_block { require "cjson" } |
init_worker_by_lua_block
1 | context: http |
每个 worker 进程的初始化,如果关闭了 master,那么它刚好在 init_by_lua* 后面运行。一般用于每个 worker 进程的定时器,后端服务器的健康检查。
init_worker_by_lua_file
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
set_by_lua_block
1 | syntax: set_by_lua_block $res <lua-script-str> |
运行原理是在 ngx_http_rewrite_module 模块里注入自定义指令,是阻塞的,耗时操作不该放在这里面执行。
ngx_http_rewrite_module 不支持非阻塞,所以 lua api 需要配合协程 yield 的不能在此命令里运行,比如
1.输出api函数(ngx.say、ngx.send_headers)
2.控制api函数(ngx.exit)
3.子请求api函数(ngx.location.capture、ngx.location.capture_multi)
4.cosocket api函数(ngx.socket.tcp、ngx.req.socket)
5.sleep api 函数(ngx.sleep)
set_by_lua_file
1 | syntax: set_by_lua_file $res <path-to-lua-script-file> [$arg1 $arg2 ...] |
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
支持变量,在代码内部可以使用 ngx.arg[1+] 来获取。
1 | location /foo { |
可以混合以下模块指令 ngx_http_rewrite_module、set-misc-nginx-module、array-var-nginx-module modules。
1 | set $foo 32; |
rewrite_by_lua_block
1 | syntax: rewrite_by_lua_block { lua-script } |
在 nginx 重写阶段执行,但是在标准模块 ngx_http_rewrite_module 之后运行,除非开启 rewrite_by_lua_no_postpone。
1 | location /foo{ |
注意:在 rewrite_by_lua_block 里执行 ngx.exit(ngx.OK) 会继续往下面阶段执行,如果想在重写阶段终止,传入 ngx.exit(status) 的 status >= 200(ngx.HTTP_OK) 和 status < 300(ngx.HTTP_SPECIAL_RESPONSE)--代表成功,或者 ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) (或者是它的兄弟状态码比如501、502..)--代表失败。
下面由于 ngx_http_rewrite_module 执行了内部跳转,所以 rewrite_by_lua_block 并不会执行。
1 | location /foo { |
如果指定为 break,则会执行。
1 | location /foo { |
rewrite_by_lua_file
1 | syntax: rewrite_by_lua_file <path-to-lua-script-file> |
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算,也支持变量。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
access_by_lua_block
1 | syntax: access_by_lua_block { lua-script } |
在访问控制阶段执行,在 ngx_http_access_module 之后执行。ngx.exit(status) 是否终止该请求同上面的 rewrite。
access_by_lua_file
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算,也支持变量。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
content_by_lua_block
1 | syntax: content_by_lua_block { lua-script } |
在内容阶段执行。
content_by_lua_file
1 | syntax: content_by_lua_file <path-to-lua-script-file> |
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算,也支持变量。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
下面这样是允许的,但是由参数来指定文件很危险,不推荐这样做。
1 | location ~ ^/app/([-_a-zA-Z0-9/]+) { |
下面这种做法推荐,从url里解析出值存入变量,然后在 index.lua 里通过如 ngx.var.id 来获取。
1 | location ~ ^/u/([a-z]+)/?([a-f0-9]*)$ { |
header_filter_by_lua_block
1 | syntax: header_filter_by_lua <lua-script-str> |
响应头过滤阶段,可以修改响应头,下面的api函数当前禁用。
1.输出api函数(ngx.say、ngx.send_headers)
2.控制api函数(ngx.redirect、ngx.exec)
3.子请求api函数(ngx.location.capture、ngx.location.capture_multi)
4.cosocket api函数(ngx.socket.tcp、ngx.req.socket)
下面会新增响应头,如果存在则覆盖。
1 | location / { |
header_filter_by_lua_file
1 | syntax: header_filter_by_lua_file <path-to-lua-script-file> |
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算,也支持变量。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
body_filter_by_lua_block
1 | syntax: body_filter_by_lua_block { lua-script-str } |
响应体块通过 ngx.arg[1] 返回,ngx.arg[2] 为 true 代表响应体内容的结束。
注意:nginx 响应过滤在一个请求里可能会被调用多次(如果以 chunk 传输),因此 lua 代码也会被执行多次。
ngx.arg[2] = true 在 nginx 内部里面即把 last_buf 设为1,last_in_chain 设为1(子请求)。
通过lua字符串或者lua表格里的字符串覆盖 ngx.arg[1] 可以改变响应体,比如下面就是把响应体转成小写再输出。
1 | location / { |
把 ngx.arg[1] 设置成空lua字符串或者nil,那么将会没有数据块会传入到接下来的响应体过滤模块。
下面在处理第一个块时,检测到 hello 字符串,然后标记为最后一个块,所以接下来的所有块会被忽略,不会返回给客户端。
1 | location /t { |
ngx.arg[1] = nil 代表丢弃当前块。
1 | location /t { |
lua代码可能会改变响应体的长度,所以应该在响应头过滤时清除 Content-Length 响应头,那么 nginx 会在响应头里加上 Transfer-Encoding: chunked。
1 | location /foo { |
下面的api函数当前禁用。
1.输出api函数(ngx.say、ngx.send_headers)
2.控制api函数(ngx.exit、ngx.exec)
3.子请求api函数(ngx.location.capture、ngx.location.capture_multi)
4.cosocket api函数(ngx.socket.tcp、ngx.req.socket)
body_filter_by_lua_file
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算,也支持变量。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
log_by_lua_block
1 | syntax: log_by_lua_block { lua-script } |
日志阶段运行,不会替换当前访问日志,在日志处理阶段之前运行。
下面的api函数当前禁用。
1.输出api函数(ngx.say、ngx.send_headers)
2.控制api函数(ngx.exit)
3.子请求api函数(ngx.location.capture、ngx.location.capture_multi)
4.cosocket api函数(ngx.socket.tcp、ngx.req.socket)
log_by_lua_file
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算,也支持变量。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
balancer_by_lua_block
1 | syntax: balancer_by_lua_block { lua-script } |
该指令可以动态的选择负载均衡的上流服务器,一般配合 ngx_proxy 和 ngx_fastcgi 模块使用。
也可以与上游连接池指令配合比如 keepalive 。在单个 upstream{} 块上,keepalive 指令在 balancer_by_lua_block 指令之后起作用。
配合 lua-resty-core 类库的 ngx.balancer 模块,可以忽略定义在 upstream{} 里所有服务器。
该 lua 代码可能会被执行多次,基于 proxy_next_upstream 指令的设置。
1 | http { |
balancer_by_lua_file
1 | syntax: balancer_by_lua_file <path-to-lua-script-file> |
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算,也支持变量。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
lua_capture_error_log
1 | syntax: lua_capture_error_log size |
设置错误日志的缓冲区大小,单位k、m。一般来说 4K 可以存储20条错误日志。如果错误日志满了,最旧的那条会被移除。
可以通过 lua-resty-core 库的 ngx.errlog 模块的 get_logs() 函数来读取日志,读取了的日志会从缓冲区里移除以便腾出空间给其他错误日志,如果读取的速度够快,则该缓冲区没必要设置的太大。
该缓冲区的日志会受 error_log 指令的日志级别影响,只会捕获到级别大于等于 error_log 指令设置的级别。当然可以使用 errlog.set_filter_level 设置更高的日志级别,很灵活。
lua_use_default_type
1 | syntax: lua_use_default_type on | off |
是否继承由 default_type 设置的默认 mime 类型,默认开启。
lua_malloc_trim
1 | syntax: lua_malloc_trim <request-count> |
设置内部 libc 运行库多少请求后释放缓存,设置太小会平凡的清理缓存,耗cpu,会节约内存。
因为它是在日志阶段运行的统计,默认只统计主请求,如果设置 log_subrequest on,那么子请求也会统计,这样到达清理缓存的零界点就会加快。
lua_code_cache
1 | syntax: lua_code_cache on | off |
对于 *_by_lua_file 指定的 lua 文件是否开启缓存。如果关闭,每次请求都会重新生成 lua虚拟机,所以改动后立即生效,适合调试阶段,非常不建议在正式环境关闭缓存。
但是如果通过 *_by_lua_block 指令直接在 nginx.conf 里配置的,更新后,还是得 reload 或重启 nginx 后才能生效,因为它属于配置的一部分。
通过 dofile 或者 loadfile 指令加载的 lua 文件不会被缓存。
lua_regex_cache_max_entries
1 | syntax: lua_regex_cache_max_entries <num> |
设置单个worker进程编译后正则的缓存数,如果在 ngx.re.match、ngx.re.gmatch、ngx.re.sub、ngx.re.gsub 设置了 o 标志,那么就会缓存该正则。
如果超过了该数目,那么超过的正则将不会缓存。
不要在正则字符串会动态变化里设置 o 标志,免得立马就达到正则上限了。
lua_regex_match_limit
1 | syntax: lua_regex_match_limit <num> |
对执行 ngx.re API 设置匹配限制,0代表使用 PCRE 库的默认值。
lua_need_request_body
1 | syntax: lua_need_request_body <on|off> |
是否读取请求体,默认情况下,nginx 是不读取请求体的。
如果请求体大小没超过 client_body_buffer_size 设置的大小,那么读取后会存入 $request_body 变量,如果超过了,会存入临时文件。
如果当前 location 有 rewrite_by_lua* 指令,那么会在重写阶段,该指令执行之前读取。如果只有 content_by_lua*指令,那么会在内容阶段,该指令执行之前读取。
如果要用到请求体,建议利用 ngx.req.read_body() 来实时读取保存,利用 ngx.req.discard_body() 来主动读取并丢弃请求体。
ssl_certificate_by_lua_block
1 | syntax: ssl_certificate_by_lua_block { lua-script } |
该lua代码会在开始 ssl 握手前执行,一般会配合 lua-resty-core 库的 ngx.ssl 和 ngx.ocsp 模块使用。
后面会有详细例子。
ssl_certificate_by_lua_file
同上,只是用来指定外部 lua 文件,支持相对路径,从当前工作目录开始算,也支持变量。
只会加载一次,所以每次改动需要 reload 才能生效,除非关闭 lua_code_cache。
lua_shared_dict
1 | syntax: lua_shared_dict <name> <size> |
定义共享内存区域,会在所有 worder 进程里共享。单位为 k、m。
1 | http { |
细节在 ngx.shared.DICT 里讲。
lua_socket_connect_timeout
1 | syntax: lua_socket_connect_timeout <time> |
设置 tcp/unix-domain 连接的超时时间,可以被 settimeout 或者 settimeouts 覆盖。单位m、s、ms。
lua_socket_send_timeout
1 | syntax: lua_socket_send_timeout <time> |
设置 tcp/unix-domain 发送的超时时间,可以被 settimeout 或者 settimeouts 覆盖。单位m、s、ms。
lua_socket_read_timeout
1 | syntax: lua_socket_read_timeout <time> |
设置 tcp/unix-domain 接收的超时时间,可以被 settimeout 或者 settimeouts 覆盖。单位m、s、ms。
lua_socket_buffer_size
1 | syntax: lua_socket_buffer_size <size> |
设置 cosocket 读取缓冲区大小。
lua_socket_pool_size
1 | syntax: lua_socket_pool_size <size> |
设置每个worker进程保存在连接池的连接数,超过了会移除最早的。
lua_socket_keepalive_timeout
1 | syntax: lua_socket_keepalive_timeout <time> |
保存在连接池里的超时连接时间,如果超过了,那么会关闭连接并从连接池移除。
lua_socket_log_errors
1 | syntax: lua_socket_log_errors on|off |
是否开启记录 tcp 或者 udp cosockets 错误日志。
lua_ssl_ciphers
1 | syntax: lua_ssl_ciphers <ciphers> |
指定允许的加密方式,可以通过 openssl ciphers 命令获取所有的加密方式。
lua_ssl_crl
1 | syntax: lua_ssl_crl <file> |
设置整数吊销列表文件,pem格式。
lua_ssl_protocols
1 | syntax: lua_ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3] |
设置 ssl/tls 协议。
lua_ssl_trusted_certificate
1 | syntax: lua_ssl_trusted_certificate <file> |
设置用来验证的信任 CA 证书文件,pem格式。
lua_ssl_verify_depth
1 | syntax: lua_ssl_verify_depth <number> |
证书链的验证深度
lua_http10_buffering
1 | syntax: lua_http10_buffering on|off |
是否开启响应体缓冲基于 http 1.0 必须要有确切的 Content-Length 响应头。
如果确切的指定了 Content-length 响应头,不管是显性指定(ngx.send_headers),或者是隐式指定(ngx.say、ngx.print),那么将不会缓冲响应体尽管已经开启。
如果通过流的形式输出大量的响应体数据,比如通过 ngx.flush,那么最好关闭响应体缓冲来节约内存。
rewrite_by_lua_no_postpone
1 | syntax: rewrite_by_lua_no_postpone on|off |
是否关闭 rewrite_by_lua* 总是在标准 rewrite 模块之后执行。
access_by_lua_no_postpone
1 | syntax: access_by_lua_no_postpone on|off |
是否关闭 access_by_lua* 总是在标准 access 模块之后执行。
lua_transform_underscores_in_response_headers
1 | syntax: lua_transform_underscores_in_response_headers on|off |
是否开启在通过 ngx.header.HEADER 库指定响应头时,将下划线 _ 转化成连字符 - 。
1 | ngx.header.content_type = 'b' |
lua_max_pending_timers
1 | syntax: lua_max_pending_timers <count> |
指定最大未到期的定时器数量,如果超过了,ngx.timer.at 直接返回 nil,和 "too many pending timers" 错误信息。
lua_max_running_timers
1 | syntax: lua_max_running_timers <count> |
指定正在运行的定时器数量上限,也就是正在回调函数里处理。如果超过了,新的到期定时器将不会执行回调函数并报错 "256 lua_max_running_timers are not enough"。
