应用篇| Tengine+Lua+Redis
Posted 5ithink
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应用篇| Tengine+Lua+Redis相关的知识,希望对你有一定的参考价值。
MAC配置Lua环境
1.luajit-2.0安装参考文章:
2.luarocks-3.0.0安装
a.下载
wget https://luarocks.org/releases/luarocks-3.0.0.tar.gz --no-check-certificate
b.配置
./configure --with-lua-include=/usr/local/include/luajit-2.0
c.编译安装
make && make install
d.验证
luarocks list
3.Intellij lua插件安装
方法1:通过Intellij idea安装
方法2:
a.直接下载lua插件
http://plugins.jetbrains.com/plugin/5055-lua
b.解压插件包放在lintellij程序包plugins目录下
c.重新启动Intellij验证
4.配置SDK
tengine+Lua+Redis应用
1.redis配置参考文章:
2.tengine配置参考文章:
vi /home/img/nginx/conf/nginx.conf
vi /home/img/nginx/conf/vhost/img.conf
location /lua/set {
default_type 'text/plain';
content_by_lua_file /home/img/app/lua/redis/set.lua;
}
location /lua/get {
default_type 'text/plain';
content_by_lua_file /home/img/app/lua/redis/get.lua;
}
b.配置lua脚本
vi /home/img/app/lua/redis/get.lua
local redis = require "redis"
local cache = redis.new()
local ok, err = cache.connect(cache, '192.168.1.202', '6379')
cache:set_timeout(60000)
if not ok then
ngx.say("failed to connect:", err)
return
end
local key = ngx.var.arg_key ;
local res, err = cache:get(key)
if not res then
ngx.say("failed to get : "..key, err)
return
end
if res == ngx.null then
ngx.say(key.."not found.")
return
end
ngx.say("get result:"..key..": ", res)
local ok, err = cache:close()
if not ok then
ngx.say("failed to close:", err);
return
end
vi /home/img/app/lua/redis/set.lua
local redis = require "redis"
local cache = redis.new()
local ok, err = cache.connect(cache, '192.168.1.202', '6379')
cache:set_timeout(60000)
if not ok then
ngx.say("failed to connect:", err)
return
end
local key = ngx.var.arg_key;
local v = ngx.var.arg_v;
res, err = cache:set(key, v)
if not ok then
ngx.say("failed to set : " .. key, err)
return
end
ngx.say("set result: ", res)
local ok, err = cache:close()
if not ok then
ngx.say("failed to close:", err);
return
end
vi /home/img/app/lua/redis/redis.lua
local sub = string.sub
local byte = string.byte
local tcp = ngx.socket.tcp
local concat = table.concat
local null = ngx.null
local pairs = pairs
local unpack = unpack
local setmetatable = setmetatable
local tonumber = tonumber
local error = error
local ok, new_tab = pcall(require, "table.new")
if not ok or type(new_tab) ~= "function" then
new_tab = function (narr, nrec) return {} end
end
local _M = new_tab(0, 155)
_M._VERSION = '0.20'
local commands = {
"append", "auth", "bgrewriteaof",
"bgsave", "bitcount", "bitop",
"blpop", "brpop",
"brpoplpush", "client", "config",
"dbsize",
"debug", "decr", "decrby",
"del", "discard", "dump",
"echo",
"eval", "exec", "exists",
"expire", "expireat", "flushall",
"flushdb", "get", "getbit",
"getrange", "getset", "hdel",
"hexists", "hget", "hgetall",
"hincrby", "hincrbyfloat", "hkeys",
"hlen",
"hmget", --[[ "hmset", ]] "hscan",
"hset",
"hsetnx", "hvals", "incr",
"incrby", "incrbyfloat", "info",
"keys",
"lastsave", "lindex", "linsert",
"llen", "lpop", "lpush",
"lpushx", "lrange", "lrem",
"lset", "ltrim", "mget",
"migrate",
"monitor", "move", "mset",
"msetnx", "multi", "object",
"persist", "pexpire", "pexpireat",
"ping", "psetex", --[[ "psubscribe", ]]
"pttl",
"publish", --[[ "punsubscribe", ]] "pubsub",
"quit",
"randomkey", "rename", "renamenx",
"restore",
"rpop", "rpoplpush", "rpush",
"rpushx", "sadd", "save",
"scan", "scard", "script",
"sdiff", "sdiffstore",
"select", "set", "setbit",
"setex", "setnx", "setrange",
"shutdown", "sinter", "sinterstore",
"sismember", "slaveof", "slowlog",
"smembers", "smove", "sort",
"spop", "srandmember", "srem",
"sscan",
"strlen", --[[ "subscribe", ]] "sunion",
"sunionstore", "sync", "time",
"ttl",
"type", --[[ "unsubscribe", ]] "unwatch",
"watch", "zadd", "zcard",
"zcount", "zincrby", "zinterstore",
"zrange", "zrangebyscore", "zrank",
"zrem", "zremrangebyrank", "zremrangebyscore",
"zrevrange", "zrevrangebyscore", "zrevrank",
"zscan",
"zscore", "zunionstore", "evalsha"
}
local sub_commands = {
"subscribe", "psubscribe"
}
local unsub_commands = {
"unsubscribe", "punsubscribe"
}
local mt = { __index = _M }
function _M.new(self)
local sock, err = tcp()
if not sock then
return nil, err
end
return setmetatable({ sock = sock }, mt)
end
function _M.set_timeout(self, timeout)
local sock = self.sock
if not sock then
return nil, "not initialized"
end
return sock:settimeout(timeout)
end
function _M.connect(self, ...)
local sock = self.sock
if not sock then
return nil, "not initialized"
end
self.subscribed = nil
return sock:connect(...)
end
function _M.set_keepalive(self, ...)
local sock = self.sock
if not sock then
return nil, "not initialized"
end
if self.subscribed then
return nil, "subscribed state"
end
return sock:setkeepalive(...)
end
function _M.get_reused_times(self)
local sock = self.sock
if not sock then
return nil, "not initialized"
end
return sock:getreusedtimes()
end
local function close(self)
local sock = self.sock
if not sock then
return nil, "not initialized"
end
return sock:close()
end
_M.close = close
local function _read_reply(self, sock)
local line, err = sock:receive()
if not line then
if err == "timeout" and not self.subscribed then
sock:close()
end
return nil, err
end
local prefix = byte(line)
if prefix == 36 then -- char '$'
-- print("bulk reply")
local size = tonumber(sub(line, 2))
if size < 0 then
return null
end
local data, err = sock:receive(size)
if not data then
if err == "timeout" then
sock:close()
end
return nil, err
end
local dummy, err = sock:receive(2) -- ignore CRLF
if not dummy then
return nil, err
end
return data
elseif prefix == 43 then -- char '+'
-- print("status reply")
return sub(line, 2)
elseif prefix == 42 then -- char '*'
local n = tonumber(sub(line, 2))
-- print("multi-bulk reply: ", n)
if n < 0 then
return null
end
local vals = new_tab(n, 0);
local nvals = 0
for i = 1, n do
local res, err = _read_reply(self, sock)
if res then
nvals = nvals + 1
vals[nvals] = res
elseif res == nil then
return nil, err
else
-- be a valid redis error value
nvals = nvals + 1
vals[nvals] = {false, err}
end
end
return vals
elseif prefix == 58 then -- char ':'
-- print("integer reply")
return tonumber(sub(line, 2))
elseif prefix == 45 then -- char '-'
-- print("error reply: ", n)
return false, sub(line, 2)
else
return nil, "unkown prefix: "" .. prefix .. """
end
end
local function _gen_req(args)
local nargs = #args
local req = new_tab(nargs + 1, 0)
req[1] = "*" .. nargs .. " "
local nbits = 1
for i = 1, nargs do
local arg = args[i]
nbits = nbits + 1
if not arg then
req[nbits] = "$-1 "
else
if type(arg) ~= "string" then
arg = tostring(arg)
end
req[nbits] = "$" .. #arg .. " " .. arg .. " "
end
end
-- it is faster to do string concatenation on the Lua land
return concat(req)
end
local function _do_cmd(self, ...)
local args = {...}
local sock = self.sock
if not sock then
return nil, "not initialized"
end
local req = _gen_req(args)
local reqs = self._reqs
if reqs then
reqs[#reqs + 1] = req
return
end
-- print("request: ", table.concat(req))
local bytes, err = sock:send(req)
if not bytes then
return nil, err
end
return _read_reply(self, sock)
end
local function _check_subscribed(self, res)
if type(res) == "table"
and (res[1] == "unsubscribe" or res[1] == "punsubscribe")
and res[3] == 0
then
self.subscribed = nil
end
end
function _M.read_reply(self)
local sock = self.sock
if not sock then
return nil, "not initialized"
end
if not self.subscribed then
return nil, "not subscribed"
end
local res, err = _read_reply(self, sock)
_check_subscribed(self, res)
return res, err
end
for i = 1, #commands do
local cmd = commands[i]
_M[cmd] =
function (self, ...)
return _do_cmd(self, cmd, ...)
end
end
for i = 1, #sub_commands do
local cmd = sub_commands[i]
_M[cmd] =
function (self, ...)
self.subscribed = true
return _do_cmd(self, cmd, ...)
end
end
for i = 1, #unsub_commands do
local cmd = unsub_commands[i]
_M[cmd] =
function (self, ...)
local res, err = _do_cmd(self, cmd, ...)
_check_subscribed(self, res)
return res, err
end
end
function _M.hmset(self, hashname, ...)
local args = {...}
if #args == 1 then
local t = args[1]
local n = 0
for k, v in pairs(t) do
n = n + 2
end
local array = new_tab(n, 0)
local i = 0
for k, v in pairs(t) do
array[i + 1] = k
array[i + 2] = v
i = i + 2
end
-- print("key", hashname)
return _do_cmd(self, "hmset", hashname, unpack(array))
end
-- backwards compatibility
return _do_cmd(self, "hmset", hashname, ...)
end
function _M.init_pipeline(self, n)
self._reqs = new_tab(n or 4, 0)
end
function _M.cancel_pipeline(self)
self._reqs = nil
end
function _M.commit_pipeline(self)
local reqs = self._reqs
if not reqs then
return nil, "no pipeline"
end
self._reqs = nil
local sock = self.sock
if not sock then
return nil, "not initialized"
end
local bytes, err = sock:send(reqs)
if not bytes then
return nil, err
end
local nvals = 0
local nreqs = #reqs
local vals = new_tab(nreqs, 0)
for i = 1, nreqs do
local res, err = _read_reply(self, sock)
if res then
nvals = nvals + 1
vals[nvals] = res
elseif res == nil then
if err == "timeout" then
close(self)
end
return nil, err
else
-- be a valid redis error value
nvals = nvals + 1
vals[nvals] = {false, err}
end
end
return vals
end
function _M.array_to_hash(self, t)
local n = #t
-- print("n = ", n)
local h = new_tab(0, n / 2)
for i = 1, n, 2 do
h[t[i]] = t[i + 1]
end
return h
end
function _M.add_commands(...)
local cmds = {...}
for i = 1, #cmds do
local cmd = cmds[i]
_M[cmd] =
function (self, ...)
return _do_cmd(self, cmd, ...)
end
end
end
return _M
3.启动redis
/home/redis/single/redis-server /home/redis/single/redis.conf
4.启动nginx
/home/img/nginx/sbin/nginx -c /home/img/nginx/conf/nginx.conf
5.测试tengin+redis+lua
a.set值保存到redis
curl http://192.168.1.200/lua/set?key=hi&v=lua
b.get值
curl http://192.168.1.200/lua/get?key=hi
参考链接:
http://www.lua.org/
https://luarocks.org
以上是关于应用篇| Tengine+Lua+Redis的主要内容,如果未能解决你的问题,请参考以下文章
技术干货听阿里云CDN安防技术专家金九讲tengine+lua开发