一、简介
nginxlua是一个基于Lua语言的模块,它将Lua语言嵌入了Nginx服务器中,可以控制Nginx的各种行为。从而方便了我们进行一些高级的web应用的开发。
二、安装和配置
安装ngx_lua组件非常简单,只需要两步即可:1.安装相关的依赖;2.下载官方的ngx_lua模块并进行编译安装,具体步骤如下:
# 先安装LuaJIT
wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz
tar -xzvf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4/
make
make install
# 下载并编译安装ngx_lua模块
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.15.tar.gz
tar -xzvf v0.10.15.tar.gz
cd lua-nginx-module-0.10.15/
./configure --with-luajit
make
make install
安装完成之后,还需要在nginx.conf中添加相关的配置。在http段中添加以下配置:
http {
...
lua_package_path "/usr/local/openresty/lualib/?.lua;;";
server {
...
location /test {
set $test "123";
content_by_lua_block {
ngx.say("test:", ngx.var.test)
}
}
...
}
}
以上示例代码中,定义了一个/test的URL,请求该URL时,将会执行后面的content_by_lua_block指定的Lua代码,输出test变量的内容。
三、基本应用
经过上面的配置,我们已经可以使用Lua脚本来进行基本的web应用程序开发了。下面我们来看几个实际应用的例子。
1、获取GET请求的参数
在编写web应用程序时,很多情况下需要从URL中获取请求参数。我们可以使用以下代码来处理这些参数:
-- get请求中,从URL中获取参数
local args = ngx.req.get_uri_args()
ngx.say("args a:", args.a, " b:", args.b)
以上代码中,使用ngx.req.get_uri_args函数来获取URL中的请求参数,args返回的是一个Lua table类型,可以根据参数名来访问相应的值。
2、获取POST请求中的body
如果是POST请求,请求参数可能在body中。我们可以使用以下代码来获取POST请求的body:
-- post请求中,从body中获取参数
ngx.req.read_body() -- 先读取body
local post_args = ngx.req.get_post_args()
ngx.say("post args a:", post_args.a, " b:", post_args.b)
以上代码中,使用ngx.req.read_body()函数来先读取body,然后再使用ngx.req.get_post_args函数来获取POST请求中的参数。
3、使用redis缓存
使用redis可以实现数据缓存,下面是redis缓存的一个示例:
-- 使用redis缓存
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local cache_key = ngx.var.uri .. ngx.var.args
local cache_value = red:get(cache_key)
if cache_value then
ngx.say("cache_value:", cache_value)
return
end
ngx.say("cache miss")
red:set(cache_key, "xxx")
red:expire(cache_key, 60)
以上代码中,使用resty.redis模块来连接redis服务器,然后使用redis:get/set等函数来进行缓存操作。
四、高阶应用
除了基本应用外,nginxlua脚本还可以实现高阶的web应用程序开发,比如nginx自身不支持HTTPS,则可以借助nginxlua脚本实现HTTPS支持。
下面是实现HTTPS的一个示例:
# 在nginx.conf中的http段下增加如下命令
lua_ssl_trusted_certificate /path/to/ssl/cert/file.crt;
lua_ssl_verify_depth 3;
# 在server段的80端口中增加如下命令
if ($scheme = https) {
rewrite ^(.*)$ https://$host$1 permanent;
}
# 在server段的443端口中增加如下命令
set $enforce_https_mode "insecure"; # 支持insecure模式
access_by_lua_block {
if ngx.var.enforce_https_mode == "force" then
if ngx.var.scheme ~= "https" then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
elseif ngx.var.enforce_https_mode == "allow" then
if ngx.var.scheme ~= "https" then
ngx.redirect(string.format("https://%s%s", ngx.var.http_host, ngx.var.request_uri), ngx.HTTP_MOVED_PERMANENTLY)
end
elseif ngx.var.enforce_https_mode == "insecure" then
if ngx.var.scheme ~= "https" then
local uri = string.format("https://%s%s", ngx.var.http_host, ngx.var.request_uri)
ngx.header["content-type"] = "text/html"
ngx.say("Please acces "..uri.." via HTTPS instead of HTTP.")
ngx.exit(ngx.HTTP_OK)
end
end
}
# 最后重启服务
nginx -s reload
以上代码中,也许有些命令可能不太直观,需要对比官方文档来理解。通过这样的配置,就可以支持HTTPS协议了。
总结
通过本文的学习,我们可以清楚的了解到nginxlua脚本的基本原理和应用。我们可以根据自己的需要,开发适用于自己web应用的高级nginxlua脚本,从而实现更好的web应用体验。