在nginx中,我们可以与lua脚本一起使用来达到web访问更高效,处理更灵活,一般情况下我们都会使用openresty来代替nginx的ngx_lua 模块,它是一款基于NGINX和 LuaJIT的Web平台,在openresty中集成了大量精良的Lua库、第三方模块以及大多数的依赖项,如lua-resty-mysql、lua-resty-redis、ngx-redis等,可以在https://github.com/openresty 上看到这些模块,有了这些模块openresty可以方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。
lua可以和nginx一起使用,主要是因为通过nginx的异步机制和lua的协程,很容易实现有数据请求时同步处理的异步实现,所谓的Lua协程,也称为协作式多线程。Lua中的协程代表一个独立的执行线程,具有自己的堆栈、自己的局部变量、PC计数器和其自己的指令指针; 与java线程不同的是,协程只通过显式调用yield函数来暂停其执行。同一时间,多协程只运行其中一个,多线程则可以运行多个。协程可以处于三种不同状态之一:暂停,运行和死亡。我们来列举一个使用redis的openresty使用配置,下面是部分nginx.conf配置:
http {
# 设置由set_by_lua, content_by_lua等指定的脚本使用的Lua模块搜索路径。类似java的classPath
# 路径字符串采用标准的Lua路径形式,;; 可用于代表原始搜索路径。
lua_package_path "/usr/local/openresty/lua_scripts/?.lua;;";
# 申请一个名为dogs的10m字典内存,共享在所有工作进程中
lua_shared_dict dogs 10m;
server {
listen 8080;
location /lua {
default_type text/html;
lua_code_cache on;
# mysql只需要替换成mysql_demo.lua脚本即可
content_by_lua_file redis_demo.lua;
}
}
}
下面是redis.lua的脚本:
local function close_redis(red)
if not red then
return
end
--释放连接(Redis连接池实现)
local pool_max_idle_time = 10000 --毫秒
local pool_size = 100 --连接池大小
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.say("set keepalive error : ", err)
end
end
local redis = require("resty.redis")
--创建实例
local red = redis:new()
--设置超时(毫秒)
red:set_timeout(1000)
--建立连接
local ip = "127.0.0.1"
local port = 6379
local ok, err = red:connect(ip, port)
if not ok then
ngx.say("connect to redis error : ", err)
return close_redis(red)
end
--调用API进行处理
ok, err = red:set("msg", "hello world")
if not ok then
ngx.say("set msg error : ", err)
return close_redis(red)
end
--调用API获取数据
local resp, err = red:get("msg")
if not resp then
ngx.say("get msg error : ", err)
return close_redis(red)
end
--得到的数据为空处理
if resp == ngx.null then
resp = '' --比如默认值
end
ngx.say("msg : ", resp)
close_redis(red)
关于openresty的安装可以参考OpenResty安装使用,关于lua脚本的知识可以参考lua官网。