ngx.header.content_type = "text/plain"; //输出头部 local user = ngx.var.arg_user //定义user变量并获取url中的参数 user值local sys = ngx.var.server_name //获取nginx中的变量 ngx.say (user); //输出至页面
ngx_lua安装
ngx_lua安装可以通过下载模块源码,编译Nginx,但是推荐采用openresty。Openresty就是一个打包程序,包含大量的第三方Nginx模块,比如HttpLuaModule,HttpRedis2Module,HttpEchoModule等。省去下载模块,并且安装非常方便。
ngx_openresty bundle: openresty
./configure --with-luajit&& make && make install
默认Openresty中ngx_lua模块采用的是标准的Lua5.1解释器,通过--with-luajit使用LuaJIT。
ngx.location.capture
location = /other { ehco ‘Hello, world!‘; } # Lua非阻塞IO location = /lua { content_by_lua ‘ local res = ngx.location.capture("/other") if res.status == 200 then ngx.print(res.body) end ‘; }
ngx.location.capture_multi
语法:res1,res2, ... = ngx.location.capture_multi({ {uri, options?}, {uri, options?}, ...})
与ngx.location.capture功能一样,可以并行的、非阻塞的发出多个子请求。这个方法在所有子请求处理完成后返回,并且整个方法的运行时间取决于运行时间最长的子请求,并不是所有子请求的运行时间之和。
# 同时发送多个子请求(subrequest) location = /moon { ehco ‘moon‘; } location = /earth { ehco ‘earth‘; } location = /lua { content_by_lua ‘ local res1,res2 = ngx.location.capture_multi({ {"/moon"}, {"earth"} }) if res1.status == 200 then ngx.print(res1.body) end ngx.print(",") if res2.status == 200 then ngx.print(res2.body) end ‘; }
set_by_lua
和set指令一样用于设置Nginx变量并且在rewrite阶段执行,只不过这个变量是由lua脚本计算并返回的。
语法:set_by_lua$res <lua-script-str> [$arg1 $arg2 ...]
location = /adder { set_by_lua $res " local a = tonumber(ngx.arg[1]) local b = tonumber(ngx.arg[2]) return a + b" $arg_a $arg_b; echo $res; }
set_by_lua_file
执行Nginx外部的lua脚本,可以避免在配置文件中使用大量的转义
location = /fib { set_by_lua_file $res "conf/adder.lua" $arg_n; echo $res; } adder.lua:
local a = tonumber(ngx.arg[1])
local b = tonumber(ngx.arg[2])
return a + b
access_by_lua和access_by_lua_file
运行在access阶段,用于访问控制。Nginx原生的allow和deny是基于ip的,通过access_by_lua能完成复杂的访问控制,比如,访问数据库进行用户名、密码验证等。
location /auth { access_by_lua ‘ if ngx.var.arg_user == "ntes" then return else Ngx.exit(ngx.HTTP_FORBIDDEN) end ‘; echo ‘welcome ntes‘; }
输出:
$ curl ‘localhost/auth?user=sohu‘ $ Welcome ntes $ curl ‘localhost/auth?user=ntes‘ $ <html> <head><title>403 Forbidden</title></heda> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>ngx_openresty/1.0.10.48</center> </body> </html>
rewrite_by_lua和rewrite_by_lua_file
实现url重写,在rewrite阶段执行。
配置:
location = /foo { rewrite_by_lua ‘ngx.exec("/bar")‘; echo ‘in foo‘; } location = /bar { echo ‘Hello, Lua!‘; }
输出:
$ curl ‘localhost/lua‘ $ Hello, Lua!
content_by_lua和content_by_lua_file
Contenthandler在content阶段执行,生成http响应。由于content阶段只能有一个handler,所以在与echo模块使用时,不能同时生效,我测试的结果是content_by_lua会覆盖echo。这和之前的hello world的例子是类似的。
location = /lua { content_by_lua ‘ngx.say("Hello, Lua!")‘; }