🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 常用命令介绍 > ## 指令 #### **lua\_code\_cache**_** **on \| off;_ **作用:**打开或关闭 Lua 代码缓存,影响以下指令: set\_by\_lua\_file , content\_by\_lua\_file, rewrite\_by\_lua\_file, access\_by\_lua\_file 及强制加载或者reload Lua 模块等.缓存开启时修改LUA代码需要重启nginx,不开启时则不用。开发阶段一般关闭缓存。 **作用域:**main, server, location, location if --- #### **lua\_package\_path **_** **../path... ;_ **作用:**设置用lua代码写的扩展库路径。 **例:**lua\_package\_path '/foo/bar/?.lua;/blah/?.lua;;'; --- #### **lua\_package\_cpath **_'/bar/baz/?.so;/blah/blah/?.so;;';_ **作用:**设置C扩展的lua库路径。 --- #### **set\_by\_lua **_$var '<lua-script>' \[$arg1 $arg2\];_ #### set\_by\_lua\_file _$var <path-to-lua-script-file> \[$arg1 $arg2 ...\];_ **作用:**设置一个Nginx变量,变量值从lua脚本里运算由return返回,可以实现复杂的赋值逻辑;此处是阻塞的,Lua代码要做到非常快.另外可以将已有的ngx变量当作参数传进Lua脚本里去,由ngx.arg\[1\],ngx.arg\[2\]等方式访问。 **作用域:**main, server, location, server if, location if **处理阶段:**rewrite --- #### content\_by\_lua _'<lua script>'; _ #### content\_by\_lua\_file _luafile;_ **作用域:**location, location if **说明:**内容处理器,接收请求处理并输出响应,content\_by\_lua直接在nginx配置文件里编写较短Lua代码后者使用lua文件。 --- #### rewrite\_by\_lua _'<lua script>' _ #### rewrite\_by\_lua\_file _lua\_file;_ **作用域:**http, server, location, location if 执行内部URL重写或者外部重定向,典型的如伪静态化的URL重写。其默认执行在rewrite处理阶段的最后. 注意,在使用rewrite\_by\_lua时,开启rewrite\_log on;后也看不到相应的rewrite log。 --- #### **access\_by\_lua **_'lua code';_ #### **access\_by\_lua\_file**_** **lua\_file.lua;_ 作用:用于访问控制,比如我们只允许内网ip访问,可以使用如下形式。 ```lua access_by_lua ' if ngx.req.get_uri_args()["token"] ~= "123" then return ngx.exit(403) end '; ``` **作用域:**http, server, location, location if --- #### **header\_filter\_by\_lua **_'lua code';_ #### **header\_filter\_by\_lua\_file **_path\_file.lua;_ 作用:设置header 和 cookie; --- #### **init\_by\_lua **_** **'lua code';_ #### **init\_by\_lua\_file **_** **lua\_file.lua;_ **作用域:**http **说明**:ginx Master进程加载配置时执行;通常用于初始化全局配置/预加载Lua模块 --- #### **init\_worker\_by\_lua **_'lua code';_ #### **init\_worker\_by\_lua\_file **_luafile.lua;_ **作用域:**http **说明:**每个Nginx Worker进程启动时调用的计时器,如果Master进程不允许则只会在init\_by\_lua之后调用;通常用于定时拉取配置/数据,或者后端服务的健康检查。 > ## 方法和常量 ```nginx ngx.arg[index] #ngx指令参数,当这个变量在set_by_lua或者set_by_lua_file内使用的时候是只读的,指的是在配置指令输入的参数. ngx.var.varname #读写NGINX变量的值,最好在lua脚本里缓存变量值,避免在当前请求的生命周期内内存的泄漏 ngx.config.ngx_lua_version #当前ngx_lua模块版本号 ngx.config.nginx_version #nginx版本 ngx.worker.exiting #当前worker进程是否正在关闭 ngx.worker.pid #当前worker进程的PID ngx.config.nginx_configure #编译时的./configure命令选项 ngx.config.prefix #编译时的prefix选项 core constans: #ngx_lua 核心常量 ngx.OK (0) ngx.ERROR (-1) ngx.AGAIN (-2) ngx.DONE (-4) ngx.DECLINED (-5) ngx.nil http method constans: #经常在ngx.location.catpure和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 http status constans: #http请求状态常量 ngx.HTTP_OK (200) ngx.HTTP_CREATED (201) ngx.HTTP_SPECIAL_RESPONSE (300) ngx.HTTP_MOVED_PERMANENTLY (301) ngx.HTTP_MOVED_TEMPORARILY (302) ngx.HTTP_SEE_OTHER (303) ngx.HTTP_NOT_MODIFIED (304) ngx.HTTP_BAD_REQUEST (400) ngx.HTTP_UNAUTHORIZED (401) ngx.HTTP_FORBIDDEN (403) ngx.HTTP_NOT_FOUND (404) ngx.HTTP_NOT_ALLOWED (405) ngx.HTTP_GONE (410) ngx.HTTP_INTERNAL_SERVER_ERROR (500) ngx.HTTP_METHOD_NOT_IMPLEMENTED (501) ngx.HTTP_SERVICE_UNAVAILABLE (503) ngx.HTTP_GATEWAY_TIMEOUT (504) Nginx log level constants: #错误日志级别常量 ,这些参数经常在ngx.log方法中被使用. ngx.STDERR ngx.EMERG ngx.ALERT ngx.CRIT ngx.ERR ngx.WARN ngx.NOTICE ngx.INFO ngx.DEBUG ################## #API中的方法: ################## print() #与 ngx.print()方法有区别,print() 相当于ngx.log() ngx.ctx #这是一个lua的table,用于保存ngx上下文的变量,在整个请求的生命周期内都有效,详细参考官方 ngx.location.capture() #发出一个子请求,详细用法参考官方文档。 ngx.location.capture_multi() #发出多个子请求,详细用法参考官方文档。 ngx.status #读或者写当前请求的相应状态. 必须在输出相应头之前被调用. ngx.header.HEADER #访问或设置http header头信息,详细参考官方文档。 ngx.req.set_uri() #设置当前请求的URI,详细参考官方文档 ngx.set_uri_args(args) #根据args参数重新定义当前请求的URI参数. ngx.req.get_uri_args() #返回一个LUA TABLE,包含当前请求的全部的URL参数 ngx.req.get_post_args() #返回一个LUA TABLE,包括所有当前请求的POST参数 ngx.req.get_headers() #返回一个包含当前请求头信息的lua table. ngx.req.set_header() #设置当前请求头header某字段值.当前请求的子请求不会受到影响. ngx.req.read_body() #在不阻塞ngnix其他事件的情况下同步读取客户端的body信息.[详细] ngx.req.discard_body() #明确丢弃客户端请求的body ngx.req.get_body_data() #以字符串的形式获得客户端的请求body内容 ngx.req.get_body_file() #当发送文件请求的时候,获得文件的名字 ngx.req.set_body_data() #设置客户端请求的BODY ngx.req.set_body_file() #通过filename来指定当前请求的file data。 ngx.req.clear_header() #清求某个请求头 ngx.exec(uri,args) #执行内部跳转,根据uri和请求参数 ngx.redirect(uri, status) #执行301或者302的重定向。 ngx.send_headers() #发送指定的响应头 ngx.headers_sent #判断头部是否发送给客户端ngx.headers_sent=true ngx.print(str) #发送给客户端的响应页面 ngx.say() #作用类似ngx.print,不过say方法输出后会换行 ngx.log(log.level,...) #写入nginx日志 ngx.flush() #将缓冲区内容输出到页面(刷新响应) ngx.exit(http-status) #结束请求并输出状态码 ngx.eof() #明确指定关闭结束输出流 ngx.escape_uri() #URI编码(本函数对逗号,不编码,而php的urlencode会编码) ngx.unescape_uri() #uri解码 ngx.encode_args(table) #将tabel解析成url参数 ngx.decode_args(uri) #将参数字符串编码为一个table ngx.encode_base64(str) #BASE64编码 ngx.decode_base64(str) #BASE64解码 ngx.crc32_short(str) #字符串的crs32_short哈希 ngx.crc32_long(str) #字符串的crs32_long哈希 ngx.hmac_sha1(str) #字符串的hmac_sha1哈希 ngx.md5(str) #返回16进制MD5 ngx.md5_bin(str) #返回2进制MD5 ngx.today() #返回当前日期yyyy-mm-dd ngx.time() #返回当前时间戳 ngx.now() #返回当前时间 ngx.update_time() #刷新后返回 ngx.localtime() #返回 yyyy-mm-dd hh:ii:ss ngx.utctime() #返回yyyy-mm-dd hh:ii:ss格式的utc时间 ngx.cookie_time(sec) #返回用于COOKIE使用的时间 ngx.http_time(sec) #返回可用于http header使用的时间 ngx.parse_http_time(str) #解析HTTP头的时间 ngx.is_subrequest #是否子请求(值为 true or false) ngx.re.match(subject,regex,options,ctx) #ngx正则表达式匹配,详细参考官网 ngx.re.gmatch(subject,regex,opt) #全局正则匹配 ngx.re.sub(sub,reg,opt) #匹配和替换(未知) ngx.re.gsub() #未知 ngx.shared.DICT #ngx.shared.DICT是一个table 里面存储了所有的全局内存共享变量 ngx.shared.DICT.get ngx.shared.DICT.get_stale ngx.shared.DICT.set ngx.shared.DICT.safe_set ngx.shared.DICT.add ngx.shared.DICT.safe_add ngx.shared.DICT.replace ngx.shared.DICT.delete ngx.shared.DICT.incr ngx.shared.DICT.flush_all ngx.shared.DICT.flush_expired ngx.shared.DICT.get_keys ndk.set_var.DIRECTIVE #不懂 ``` > ## 方法详细介绍 ### ngx.arg > 语法:val = ngx.arg \[index\] 上下文:set\_by\_lua \*,body\_filter\_by\_lua \* 描述:当在set\_by\_lua \*指令的上下文中使用时,此表是只读的,并保存config指令的输入参数: ```lua value = ngx.arg[n] ``` 例子: ```nginx location /foo_sum { default_type text/html; set $a 32; set $b 56; set_by_lua $sum 'return tonumber(ngx.arg[1]) + tonumber(ngx.arg[2])' $a $b; echo "sum = ${sum}"; } ``` ## ngx.location.capture > 语法: _res = ngx.location.capture\(uri, options?\)_ 上下文: _rewrite\_by\_lua \*,\* access\_by\_lua,content\_by\_lua \*_ 是一个同步非阻塞的NGINX子请求uri NGINX的子请求提供了一个非常强大的方式去实现非阻塞的内部请求,或者其他的C模块,比如 ngx\_proxy, ngx\_fastcgi, ngx\_memc, ngx\_postgres, ngx\_drizzle, 甚至ngx\_lua自己等等。 当然,这些子请求仅仅是模拟HTTP请求,但是并没有额外的 HTTP/TCP,所有的进程都是C级别的 子请求完全不同与HTTP 301/302。 这里有个基本的例子: ```nginx res = ngx.location.capture(uri) ``` 返回与4插槽,一个Lua表:`res.status`,`res.header`,`res.body`,和`res.truncated`。 `res.status` 用于保存子请求响应的响应状态代码。 `res.header`持有子请求的响应头,这是一个正常的Lua表。对于多值响应头,该值是保存所有的顺序它们出现的值的Lua(阵列)表。例如,如果子请求响应报头包含以下几行: 返回一个LUA的TABLE,三个值\(res.status, res.header, and res.body\)。 res.header包含了所有的子请求的头的信息,它是一个普通的LUA TABLE。比如多个值的相应头,他们以数组的形式按照顺序返回出现。例如:子请求包含了如下信息: ```nginx Set-Cookie: a=3 Set-Cookie: foo=bar Set-Cookie: baz=blah ``` 然后`res.header["Set-Cookie"]`将被评估,以表中的值 `{"a=3", "foo=bar", "baz=blah"}`。 `res.body`持有子请求的响应体数据,这些数据可能会被截断。你总是需要检查 `res.truncated`布尔标志,看是否`res.body`包含截断数据。这里的数据截断只能由那些不可恢复的错误在你的子请求一样,远端中止在响应体数据流的中间,或当你的子请求接收从响应体数据的读取超时发生过早的连接的情况下造成的遥控器。URI查询串可以串联到的URI本身,例如: ```nginx res = ngx.location.capture('/foo/bar?a=3&b=4') ``` 像名为位置`@foo`不允许由于nginx的核心的限制。使用与组合正常位置`internal`指令准备仅供内部使用的位置。 可选选项表可以喂的第二个参数,它支持的选项: * `method` 指定子请求的请求方法,只接受常量一样`ngx.HTTP_POST`。 * `body` 指定子请求的请求体(仅字符串值)。 * `args` 指定子请求的URI查询参数(这两个字符串值和Lua表被接受) * `ctx` 指定一个Lua表是[ngx.ctx](https://github.com/openresty/lua-nginx-module#ngxctx)为子请求表。它可以是当前请求的[ngx.ctx](https://github.com/openresty/lua-nginx-module#ngxctx)表,这有效地使母体和其子请求共享完全相同的上下文表。此选项最初是在引进`v0.3.1rc25`发行。 * `vars` 采取持有的值设置指定的Nginx变量在子请求作为此选项的值一个Lua表。此选项最初是在引进`v0.3.1rc31` 发行。 * `copy_all_vars` 指定是否在当前请求所讨论的子请求的所有的Nginx变量值复制。在子请求nginx的变量的修改将不会影响当前(父)的请求。此选项最初是在引进`v0.3.1rc31`发行。 * `share_all_vars` 指定是否共享的子请求与当前(父)要求所有的Nginx变量。在子请求Nginx的变量的修改将影响当前(父)的请求。启用此选项可能会导致因不良副作用难以调试问题,被认为是不好的,有害的。只有启用该选项,当你完全知道自己在做什么。 * `always_forward_body` 当设置为true,当前(父)的请求的请求体总是会被转发到,如果创建的子请求`body`未指定选项。无论是通过读取请求体 [()ngx.req.read\_body](https://github.com/openresty/lua-nginx-module#ngxreqread_body)或[lua\_need\_request\_body上](https://github.com/openresty/lua-nginx-module#lua_need_request_body)会被直接转发到子请求不创建子请求(无论请求体数据在内存中缓存或临时文件缓存)时复制整个请求体数据。默认情况下,这个选项是`false`和时`body` 没有指定选项时,当前的(父)请求的请求体,当子请求取只转发`PUT`或`POST`请求方法。 发出一个POST子请求,例如,可以做如下: ```nginx res = ngx.location.capture( '/foo/bar', { method = ngx.HTTP_POST, body = 'hello, world' } ) ``` 看到比其他POST HTTP方法的常量方法。该`method`选项是`ngx.HTTP_GET`默认。 该`args`选项可以指定额外的URI参数,例如: ```nginx ngx.location.capture('/foo?a=1', { args = { b = 3, c = ':' } } ) ``` 相当于 ```nginx ngx.location.capture('/foo?a=1&b=3&c=%3a') ``` 也就是说,该方法将根据规则URI参数逃脱键和值一起将它们连接起来成为一个完整的查询字符串。对于作为通过的Lua表的格式`args`参数是相同于使用的格式[ngx.encode\_args](https://github.com/openresty/lua-nginx-module#ngxencode_args)方法。该`args`选项也可以采取简单的查询字符串: ```lua ngx.location.capture('/foo?a=1', { args = 'b=3&c=%3a' } } ) ``` 这在功能上等同于前面的例子。 该`share_all_vars` 选项控制是否将当前请求和子请求之间共享nginx的变量。如果此选项设置为`true` ,那么当前请求和相关的子请求将共享相同的Nginx变量的作用域。因此,通过一个子请求更改了Nginx的变量将影响到当前的请求。 应小心使用此选项,变量的作用域共享可以有意想不到的副作用。的`args`,`vars`或`copy_all_vars`选项通常优于代替。这个选项被设置为`false`默认. ```nginx location /other { set $dog "$dog world"; echo "$uri dog: $dog"; } location /lua { set $dog 'hello'; content_by_lua_block { res = ngx.location.capture("/other", { share_all_vars = true }); ngx.print(res.body) ngx.say(ngx.var.uri, ": ", ngx.var.dog) } } ``` 访问位置`/lua`给: ```nginx /other dog: hello world /lua: hello world ``` 该`copy_all_vars`选项提供父请求的Nginx的变量的副本子请求时这样子请求发出。由这样子请求对这些变量所做的更改不会影响父请求或任何其他子请求共享父请求的变量。 ```nginx location /other { set $dog "$dog world"; echo "$uri dog: $dog"; } location /lua { set $dog 'hello'; content_by_lua_block { res = ngx.location.capture("/other", { copy_all_vars = true }); ngx.print(res.body) ngx.say(ngx.var.uri, ": ", ngx.var.dog) } } ``` 请求`GET /lua`将给输出 ```nginx /other dog: hello world /lua: hello ``` 请注意,如果两者`share_all_vars`并`copy_all_vars`都设置为true,则`share_all_vars`优先。 除了上述两个设置,有可能使用在子请求变量的值`vars`选项。这些变量的变量共享或复制已评估后设置,并且提供了对编码它们以URL参数,并在Nginx的配置文件反向转义它们传递特定值应用于一个子请求的更有效的方法: ```nginx location /other { content_by_lua_block { ngx.say("dog = ", ngx.var.dog) ngx.say("cat = ", ngx.var.cat) } } location /lua { set $dog ''; set $cat ''; content_by_lua_block { res = ngx.location.capture("/other", { vars = { dog = "hello", cat = 32 }}); ngx.print(res.body) } } ``` 访问`/lua`将产生的输出: ```nginx dog = hello cat = 32 ``` 该`ctx`选项可用于指定自定义的Lua表作为[ngx.ctx](https://github.com/openresty/lua-nginx-module#ngxctx)为子请求表. ```nginx location /sub { content_by_lua_block { ngx.ctx.foo = "bar"; } } location /lua { content_by_lua_block { local ctx = {} res = ngx.location.capture("/sub", { ctx = ctx }) ngx.say(ctx.foo); ngx.say(ngx.ctx.foo); } } ``` 然后请求`GET /lua 输出:` ```lua bar nil ``` 另外,也可以使用这个`ctx`选项共享同一[ngx.ctx](https://github.com/openresty/lua-nginx-module#ngxctx)电流(父)请求和子请求之间的表: ```nginx location /sub { content_by_lua_block { ngx.ctx.foo = "bar"; } } location /lua { content_by_lua_block { res = ngx.location.capture("/sub", { ctx = ngx.ctx }) ngx.say(ngx.ctx.foo); } } ``` 请求`GET /lua`产生的输出:bar