第一个问题是:
网站平时都操作数据库很正常,但是遇到大流量或者正好有个慢查询同时运行时,系统报:
lua tcp socket read timed out, client: 30.200.15.122, server: localhost, request: "POST /"
failed to exe sql: select * from XXXX bad result: failed to receive packet header: timeout: nil: nil.
发现需要重试。
网上查找资料后发现(网页记不清了),这个mysql错误是因为:上一个sql超时了(超时默认10s,延长超时也没用),导致数据没有被读取完,导致下一个sql无法执行。这时应该怎么重试呢?有办法将未读完的读完吗?不知道是不是这样。
我的代码:
sqlstr="select * from XXX"
local res, err, errno, sqlstate = db:query(sqlstr)
if not res then
ngx.log(ngx.ERR,"failed to exe sql: " ,sqlstr," ","bad result: ", err, ": ", errno, ": ", sqlstate, ".")
local res, err, errno, sqlstate = db:query(sqlstr)
if not res then
ngx.log(ngx.ERR,"Retry failed to exe sql: " ,sqlstr," ","bad result: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
end
function mysql_pool:query(sql)
local ret, client = self:get_connect()
if not ret then
return false, client, nil
end
local result, errmsg, errno, sqlstate = client:query(sql)
self:close()
if not result then
errmsg = concat_db_errmsg("mysql.query_failed:", errno, errmsg, sqlstate)
return false, errmsg, sqlstate
end
return true, result, sqlstate
end
第二个问题是关于 ngx.ctx.XXX 在大流量时会不会混乱,我用的版本是 ngx_openresty-1.7.4.1
在 access_by_lua_file 中我用 ngx.ctx.jsonstr 保存了post过来的json字符串
然后 content_by_lua_file 里设置json中的一个属性单独保存,ngx.ctx.orderid=postval.orderid (postval是jsonstr 转化成的json),在content_by_lua_file 接下来的处理中插入数据库,sql差不多如下,
"insert into `log` (orderid,logtime,operator,content,jsoncontent) values ('" .. ngx.ctx.orderid.. "',now(),'" .. soperator .. "','" .. scontent .. "','" .. ngx.ctx.jsonstr.. "')"
出现的问题是平时没有一点问题,如果流量很大时,数据库中有较少一部分会错乱,如 orderid 和 jsoncontent中的orderid 不一致。
跟踪了很久代码,因为逻辑很简单,没看到逻辑问题,当然也不能完全排除,主要问一下各位有遇到这个问题吗?
谢谢各位,谢谢。