ngx_lua知识点

1、

lua_code_cache on/off;

场景:该命令使用的上下文:http, server, location, location if

作用:是ngx_lua模块的一条指令,它为*_by_lua_file(比如content_by_lua_file)指令以及lua模块指定开启或关闭lua代码缓存,set_by_lua_file, content_by_lua_file, access_by_lua_file, 等等指令引用的Lua文件将不再缓存到内存, 并且所有Lua模块每次都会从头重新加载. 这样就可以避免修改lua代码然后必须重启nginx才能生效的问题,当然直接写在nginx.conf中的代码比如content_by_lua指定的代码不会实时更新,还是需要重启nginx才能生效。有优点当然也有缺点,这种每次请求都是重新加载lua模块的操作对性能有极大的影响,因此只能在开发环境关闭缓存,实际生产环境不能关闭lua代码缓存。

打开lua代码缓存带来的问题是如果lua代码中定义了全局变量,此使全局变量的生命周期是每次请求都存在,当第一次请求使用require加载lua模块,会将一些状态信息保存到全局变量中,当后面的请求再次使用require加载lua模块时会直接返回之前已经加载过的lua模块的table,而这些table所需要的信息在后面请求的全局变量中是不存在的,所以出现访问的变量未初始化的情况,就会导致500错误。

2、静态分析-编译时检查

可以在编译时检查未定义的全局变量,比如Lua 5.1编译器:

luac -p -l myprogram.lua | grep ETGLOBAL

Lua5.2/5.3编译器:

luac -p -l myprogram.lua | grep 'ETTABUP.*_ENV'

具体检测未定义变量的详细方法见:http://lua-users.org/wiki/DetectingUndefinedVariables

2、lua_shared_dict sysStatusdb 1m

定义一块名为sysStatusdb的共享内存空间,内存大小为1m,该内存空间对所有nginxworker进程都是可见的。

3、lua_package_path

设置OpenResty的文件寻址路径,即Lua扩展库的搜寻路径,默认是’;;’路径。比如

lua_package_path 'ngx-lua/src/?.lua;;';

就会将ngx-lua/src/作为搜寻目录,搜寻其下的目录的lua文件,lua代码中的require语句会替换问号,比如require “util.LuaJson”;就会搜寻ngx-lua/src/util/LuaJson.lua文件。

4、ngx.log(ngx.ERR,"ngx.var.request_method===", ngx.var.request_method)

输入出日志:

Ngx.ERR是日志级别

日志级别从高到低依次是

ngx.STDERR 标准输出

ngx.EMERG 紧急错误

ngx.ALERT 警告

ngx.CRIT 严重的系统故障

ngx.ERR 错误

ngx.WARN 可以忽略的提醒

ngx.NOTICE 需要注意的提醒

ngx.INFO 信息

ngx.DEBUG 调试

5、pcall可以捕获执行的异常,可以在安全模式下执行代码,比如加载其他lua模块,这样如果加载出错,可以清空赋值的变量,避免其他代码加载这个模块出错。

6、ngx.exit(status)

当传入的status >= 200,200即ngx.HTTP_OK,ngx.exit() 会中断当前请求,并将传入的状态码(status)返回给nginx,比如404错误。

当传入的status == 0,0即ngx.OK,则 ngx.exit() 会中断当前执行的ngx-lua模块处理请求的阶段,如content_by_lua*,进而继续执行下面的部分。

这里的status可以是ngx-lua所定义的所有HTTP状态码常量(https://www.nginx.com/resources/wiki/extending/api/http/?highlight=ngx_ok)和两个ngx_lua模块内核常量NGX_OK、NGX_ERROR,如果传入其他的ngx-lua内核常量会夯住ngx进程。

一般将ngx.exit(status)后面跟上return来保证请求被终止

7、ngx.eof()

只是指定了响应流输出结束,中断HTTP请求,后面的代码逻辑还会继续在服务端执行

8、module(...,package.seeall)

Lua语言中定义包的语句,来显示申明一个包,包的名字与定义包的文件的名字相同。

Module的第一个参数就是包名,缺省就是文件名,第二个参数package.seeall,默认在定义了module()之后,前面定义的全局变量就都不可用了,包括print函数等,如果要让之前的全局变量可见,就必须在定义module的时候加上package.seeall参数。

严格来说不推荐这种使用方式,是因为,本意是想引用这个包内的函数,但是包内却可以访问全局变量,这样就污染了全局变量,因为包内有可能向全局变量增加变量,这样其他没有引用这个包的地方也可以使用这个包定义的全局变量了。

9、慎用#获取table的长度,#只对键为数字的有效,如果键是字符那么#获取的表长度就是0

10、获取GET请求的参数

ngx.req.get_uri_args()

返回的是一个table

11、获取POST请求的参数

ngx.req.get_post_args()

一般post请求会将参数以json格式发送,因此还可以使用ngx.req.get_body_data(),接收的是一个string,可以进行json解码。

12、获取请求头

ngx.req.get_headers()

返回的是一个table,可以根据键获取对应的请求头内容,

ngx.req.raw_header()

返回的是请求头的字符串形式。

13、ngx.location.capture_multi

并行的、非阻塞的发出多个子请求,这个方法在所有子请求完成之后返回,整个方法的运行时间取决于运行时间最长的请求,而不是所有请求时间之和。实例:

local firResp,secResp = ngx.location.capture_multi({{fir_url},{sec_url}});

最好将所有的网络IO和磁盘IO委托给Nginx子请求完成比如ngx.location.capture,即ngx lua api,而不是lua api,因为这有可能导致nginx的事件循环被阻塞。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值