在一台nginx服务器上,本地弄了个redis,使用https://github.com/openresty/lua-resty-redis 做一些简单的逻辑判断使用,可奇怪的时候一直产生大量的time_wait,机器连接数总共才2000多,可time_wait居然要2万多。

按理说lua-resty-redis是有连接池的,看了下写法也没有问题啊,网上那个坑1坑2坑3也都没有问题啊,可就是继续大量time_wait。 https://moonbingbing.gitbooks.io/openresty-best-practices/web/conn_pool.html  这段反反复复看了好多遍,也没想出是什么原因。

从time_wait的产生分析也是nginx产生的,不是本地redis配置的问题,而且redis也本来就配置的keepalive。

于是就继续使用tcpdump大法了,看看为什么nginx发了FIN没有得到ack。dump出来结果也是这样。

redis-dump

redis-server这里没有对FIN 进行ack, 导致nginx一直保持time_wait状态,而且这个状态必须要等1分钟后2MSL(最大报文段生存时间)才会到close状态。这个是无法通过sysctl.conf来进行修改的。

这个时候就完全到到lua-resty-redis这个模块的问题,去github上更新了最新的,然后看到文档里又有依赖对应的nginx-lua版本,也都检查了没有问题。

这个时候那就只能是代码本身的问题,看lua-resty-redis的邮件列表也没有什么人说有不能keepalive的问题。

然后把代码恢复成官网事例一样,结果发现好使。

过了一遍代码果然找到了问题所在

if not ngx.var.cookie_userid then
    userid = 0
--    return
end

原先代码里是判断如果cookie里没有userid就直接return,但是一旦return出来之后就用不到后面的keepalive了,所以将这里直接赋值一个0无效的userid,然后再继续后面的判断。

从这个问题来看主要还是对lua的循环跳出机制还是不够了解,忙活了4个小时答案就是这个。

Share Your Thought