openresty 引入 lua语法

1)openresty中nginx引入lua方式

  • 1)xxx_by_lua --->字符串编写方式

  • 2) xxx_by_lua_block ---->代码块方式

  • 3) xxx_by_lua_file ---->直接引用一个lua脚本文件

第一种:content_by_lua

编辑nginx.conf

location /testlua {
  content_by_lua "ngx.say('hello world')";
}

输出了hello world

content_by_lua 方式,参数为字符串,编写不是太方便。

第二种:content_by_lua_block

location /testlua {
  content_by_lua_block {
       ngx.say("hello world");
  } 
}

content_by_lua_block {} 表示内部为lua块,里面可以应用lua语句

第三种:content_by_lua_file

content_by_lua_file 就是引用外部lua文件

二)openresty使用lua打印输出案例

  • ngx.header:输出响应头;

  • ngx.print:输出响应内容体;

  • ngx.say:通ngx.print,但是会最后输出一个换行符;

  • ngx.exit:指定状态码退出。

三)openresty使用lua常用的api

1)ngx.var : 获取Nginx变量 和 内置变量

ngx.var.xxx 示例

http://127.0.0.1/var?a=1&b=2,结果为6

注意:ngx.var.c 此变量必须提前声明;

另外对于nginx location中使用正则捕获的捕获组可以使用ngx.var[捕获组数字]获取;

http://127.0.0.1/var/222222,结果var[1]:222222

2)ngx.req请求模块的常用api

获取带中划线的请求头时请使用如headers.user_agent这种方式;如果一个请求头有多个值,则返回的是table;

3)获取请求参数

  • ngx.req.get_uri_args:获取url请求参数,其用法和get_headers类似; (获取get方式的请求参数)

  • ngx.req.get_post_args:获取post请求内容体,其用法和get_headers类似, 但是必须提前调用ngx.req.read_body()来读取body体 (也可以选择在nginx配置文件使用lua_need_request_body on;开启读取body体, 但是官方不推荐);

    • (获取post方式的请求参数)

  • ngx.req.get_body_data:为解析的请求body体内容字符串。

结果:

4) ngx.req其他常用的api

ngx.req.raw_header()这个函数返回值为字符串。

5)编码解码

  • ngx.escape_uri/ngx.unescape_uri : uri编码解码;

  • ngx.encode_args/ngx.decode_args:参数编码解码;

  • ngx.encode_base64/ngx.decode_base64:BASE64编码解码;

6)md5加密api

7)nginx获取时间

之前介绍的os.time()会涉及系统调用,性能比较差,推荐使用nginx中的时间api

  • ngx.time() --返回秒级精度的时间戳

  • ngx.now() --返回毫秒级精度的时间戳

就是通过这两种方式获取到的只是nginx缓存起来的时间戳,不是实时的。 所以有时候会出现一些比较奇怪的现象,比如下面代码:

正常来说,t2应该大于t1才对,但由于nginx没有及时更新(缓存的)时间戳,所以导致t2和t1获取到的时间戳是一样的。 那么怎样才能强迫nginx更新缓存呢?调用多一个ngx.update_time()函数即可:

8)ngx.re模块中正则表达式相关的api

ngx.re.match 只有第一次匹配的结果被返回,如果没有匹配,则返回nil;或者匹配过程中出现错误时, 也会返回nil,此时错误信息会被保存在err中。

当匹配的字符串找到时,一个Lua table captures会被返回,

captures[0]中保存的就是匹配到的字串,

captures[1]保存的是用括号括起来的第一个子模式(捕获分组)的结果,

captures[2]保存的是第二个子模式(捕获分组)的结果,依次类似。

上面例子中,匹配的字符串是1234,因此m[0] == "1234",

备注:有没有注意到,我们每次修改都要重启nginx,这样太过于麻烦,我们可以用 content_by_lua_file 引入外部lua,这样的话 只要修改外部的lua,就可以了,不需要重启nginx了。 注意需要把lua_code_cache 设置为off

语法:lua_code_cache on | off

默认: on

适用上下文:http、server、location、location if

这个指令是指定是否开启lua的代码编译缓存,开发时可以设置为off,以便lua文件实时生效,

如果是生产线上,为了性能,建议开启。

9)标准日志输出

日志输出级别

示例:

日志输出级别使用的 error,只有等于或大于这个级别的日志才会输出

对于应用开发,一般使用 ngx.INFO 到 ngx.CRIT 就够了。生产中错误日志开启到 error 级别就够了

10)重定向 ngx.redirect

11)不同阶段共享变量

ngx.ctx 全局共享变量

在 OpenResty 的体系中,可以通过共享内存的方式完成不同工作进程的数据共享, 本地内存方式 去让不同的工作进程共享数据

openresty有不同处理阶段,在不同的处理阶段,如何共享数据

可以通过 Lua 模块方式完成单个进程内不同请求的数据共享。如何完成单个请求内不同阶段的数据共享呢

ngx.ctx 表就是为了解决这类问题而设计的。参考下面例子:

结果:79

ngx.ctx.xxxxx

首先 ngx.ctx 是一个表,所以我们可以对他添加、修改。它用来存储基于请求的 Lua 环境数据, 其生存周期与当前请求相同 (类似 Nginx 变量)。它有一个最重要的特性:

单个请求内的 rewrite (重写),access (访问),和 content (内容) 等各处理阶段是保持一致的。

额外注意,每个请求,包括子请求,都有一份自己的 ngx.ctx 表。例如:

ngx.location.capture 这种方式内部跳转,访问的url不会发生跳转。

访问/main的结果

ngx.ctx 表查询需要相对昂贵的元方法调用,这比通过用户自己的函数参数直接传递基于请求的数据要慢得多。 所以不要为了节约用户函数参数而滥用此 API,因为它可能对性能有明显影响。

由于 ngx.ctx 保存的是指定请求资源,所以这个变量是不能直接共享给其他请求使用的。

每个请求地址都是隔离的

更多api使用

更多api使用 https://www.nginx.com/resources/wiki/modules/lua/#nginx-api-for-lua

操作指令

API

常量说明

HTTP 请求方式

HTTP 返回状态

Last updated

Was this helpful?