1.原来系统的架构是用户的请求经过运维的nginx负载均衡,到达我的两个nginx,我的nginx将请求转发到后端的两个resin,resin里面的java web应用程序读取redis,构造结果,然后将请求返回用户。
2.我觉得这个功能是个瓶颈,刚好接触到春哥的openresty,就打算用lua改写这部分逻辑,现在的逻辑是用户的请求经过运维的nginx负载均衡,到达我的nginx,我的nginx直接使用春哥的LuaRestyRedisLibrary模块读取redis,并用cjson模块对结果进行构造,返回用户
但是经过测试人员的测试发现,性能并没有提高多少,甚至还不如转发给resin用,java web程序处理,请问这个是怎么回事呢?
![]()
上图是用jmeter测试的通过java web程序去读取redis,56个并发,跑了120s,
![]()
上图是jmeter测试的通过lua去读取redis,同样是56个并发,跑了120s
看出性能没多少提高。
lua代码如下
location = /m/user/showWall {
default_type 'application/json; charset=UTF-8';
lua_code_cache on;
content_by_lua_file conf/showwall.lua;
}
showwall.lua 是仿照春哥的例子写的。
local dk = ngx.var.arg_dk;
if dk == nil then
ngx.req.read_body()
local args = ngx.req.get_post_args()
for key, val in pairs(args) do
if key == "dk" then
if type(val) == "table" then
dk = table.concat(val,",")
else
dk = val
end
end
end
if dk == nil then
ngx.say("{\"s\":1,\"l\":[]}")
return
end
end
local dkey = "dev_soft_score_" .. dk
-- ngx.say(dkey)
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000) -- 1 sec
-- or connect to a unix domain socket file listened
-- by a redis server:
-- local ok, err = red:connect("unix:/path/to/redis.sock")
local ok, err = red:connect("内网ip", 6379)
if not ok then
ngx.say("{\"s\":1,\"l\":[]}")
--ngx.say("failed to connect: ", err)
return
end
local res, err = red:get(dkey)
if not res then
ngx.say("{\"s\":1,\"l\":[]}")
--ngx.say("failed to get ad_adlist_onsale: ", err)
return
end
local score = tonumber(res) or 0
--ngx.say(res," -- ",score)
if score <= 0 then
ngx.say("{\"s\":1,\"l\":[]}")
return
end
local res, err = red:hget("ad_adlist_onsale","list")
if not res then
ngx.say("{\"s\":1,\"l\":[]}")
--ngx.say("failed to get ad_adlist_onsale: ", err)
return
end
--ngx.say(res)
if res == ngx.null or res == "[]" then
ngx.say("{\"s\":1,\"l\":[]}")
--ngx.say("ad_adlist_onsale not found.")
return
end
--ngx.say("ad_adlist_onsale: ", res)
local cjson = require "cjson"
scorelist = cjson.decode(res)
local adtables = {}
--ngx.say("cjson ",scorelist)
for k,v in pairs(scorelist) do
local adtable = {}
for k2,v2 in pairs(v) do
if k2 =="devprice" then
--ngx.say("key is ",k2,"value is ",v2)
v22 = math.ceil(v2*score)
--ngx.say("v22 is ",v22)
adtable["s"]=v22
elseif k2 == nil or k2 ==ngx.null then
--ngx.say("k2 is nil")
elseif k2 =="appurl" then
adtable["du"]=v2
elseif k2 =="appsize" then
adtable["hs"]= v2
elseif k2 =="imgurl" then
adtable["i"] = v2
elseif k2 =="appid" then
adtable["id"] = v2
elseif k2 =="key" then
adtable["k"] = v2
elseif k2 =="appname" then
adtable["n"] = v2
elseif k2 =="devprice" then
adtable["s"] = v2
elseif k2 =="packagename" then
adtable["sc"] = v2
elseif k2 =="softsize" then
adtable["si"] = v2
elseif k2 =="appversion" then
adtable["vc"] = v2
elseif k2 =="describe" then
adtable["ab"] = v2
else
end
end
adtables[k]=adtable
end
local alltable = {}
alltable["s"]=1
alltable["l"]=adtables
local mysorelist = cjson.encode(alltable)
--ngx.say("----------------------")
ngx.say(mysorelist)
-- put it into the connection pool of size 100,
-- with 0 idle timeout
local ok, err = red:set_keepalive(0, 100)
if not ok then
--ngx.say("failed to set keepalive: ", err)
return
end