场景描述:test_client(jmeter) -> nginx -> redis
问题表现:nginx频繁报错redis cannot assign requested address,查看nginx网络连接情况,发现有大量TIME_WAIT的连接,并且test_client的tps上不去。大量的TIME_WAIT状态使得local port在TIME_WAIT持续期间不能被再次分配,即没有可用的local port,最终导致新建连接失败。
问题分析一:
大量TIME_WAIT出现的主要原因是nginx频繁与服务端建立tcp短连接后,又主动关闭tcp连接引起的。我们使用的openresty的redis库(resty.redis)已经有连接池的概念,且关闭tcp连接时使用set_keepalive方式,所以搞不清楚为什么nginx会频繁关闭tcp连接,导致出现大量TIME_WAIT的tcp连接。
问题分析二:
lua-resty-redis的set_keepalive函数最终调用的是lua-nginx-module的tcpsock:setkeepalive函数,此函数有两个参数(max_idle_timeout, pool_size),即最大空闲时间和最大连接池大小。使用set_keepalive把该连接放到连接池后,该连接到达最大空闲时间或者连接池到达连接池最大值时,会把连接池中最久未使用的连接关闭掉。原文如下:</