function _M.get_messages(queue, receiver, start, max, retry_num) assert(start>=0) assert(max>=1)
local result = {} local index = string.format('%s:%d,%d', queue, start, max) log(INFO, index)
local db = database.connect() if not db then return 500, 'failed to connect to mysql' end
for id = start,start+max-1 do local message = cache_message:get(queue..':'..id) if message then table.insert(result, message) else -- 1. select from mysql if cache miss log(INFO, 'message #', id, ' miss, query message ', index) local sql = string.format('select * from %s_msg where id >= %d limit %d', queue, start, max) log(INFO, 'sql: ', sql) local err, errcode, sqlstate result, err, errcode, sqlstate = db:query(sql) assert(next(result)) -- print('res: ', inspect(result)) if not result then log(ERR, "bad result: ", err, ": ", errcode, ": ", sqlstate, ".") return 500, 'mysql error' end set_messages(queue, result) break end end
-- 2. insert result into mysql local values = {} local sql if retry_num > 0 then for i, message in ipairs(result) do table.insert(values, string.format("(%d, '%s')", message['id'], receiver)) end sql = string.format([[insert into %s_rst(m_id, receiver)values%s]], queue, table.concat(values, ',')) else -- handle the special case when retry_num is 0 for i, message in ipairs(result) do table.insert(values, string.format("(%d, '%s', 'failed')", message['id'], receiver)) end sql = string.format([[insert into %s_rst(m_id, receiver, status)values%s]], queue, table.concat(values, ',')) end log(INFO, 'sql: ', sql)
local res, err, errcode, sqlstate = db:query(sql) -- print('res: ', inspect(res)) if not res then log(ERR, "bad result: ", err, ": ", errcode, ": ", sqlstate, ".") return 500, 'mysql error' end
-- 3. update queue.recv.last and queue.recv.processing set_last_id(queue, receiver, result[#result]['id']) if retry_num > 0 then update_processing_num(queue, receiver, #result) end
database.keepalive(db)
return 200, resultend
local message = cache_message:get(queue..':'..id)
local sql = string.format('select * from %s_msg where id >= %d limit %d', queue, start, max)
local index = string.format('%s:%d,%d', queue, start, max)
这一行似乎可以去掉了?index 只在日志的时候用到,可以交由 ngx.log 拼接(实际上线上环境下应该是不会处理的),不需要事先创建出来。
当然这个不会是瓶颈所在。
我觉得影响性能的应该是 insert into 那一块,每个 id 都会创建一个新的字符串,最后还会啪的一下拼出个较长的 SQL 语句出来。LuaJIT 在执行 lj_str_new 的时候,会先去查找是否有同样的字符串存在,没有才会创建新的。
但是这里的字符串个个不同,是没法复用的,走的代码路径会更长。不过这点似乎没什么好办法解决,除非 mysql 库支持 prepare statement……
另外我看你的 LuaJIT 版本比较旧,是否能试下 openresty/luajit2 的最新版呢?他们在新版本上修改了 luajit 的字符串哈希逻辑。虽然这么做是出于提高安全性的目的,不过说不定也能改善你的应用的 lj_str_new 性能呢。
--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty+subscribe@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+unsubscribe@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html
for id = start,start+max-1 do
local message = cache_message:get(queue..':'..id)
...
end
local sql = string.format('select * from %s_msg where id >= %d limit %d', queue, start, max)
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
订阅: 请发空白邮件到 openresty+subscribe@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+unsubscribe@googlegroups.com
(%d, '%s', 'failed') 这一块拆成 array 传过去,看看能不能直接把 string.format 都省了。
--
--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html
---
您收到此邮件是因为您订阅了Google网上论坛上的“openresty”群组。
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到openresty+...@googlegroups.com。
要在网络上查看此讨论,请访问https://groups.google.com/d/msgid/openresty/f8ee56e4-0866-40b2-8832-7d72d9a532d7%40googlegroups.com。