「golang」关于TIME_WAIT优化

【问题现象】

项目遗留问题:项目一般用redis作为缓存,并发量突增时很容易出现TCP连接失败(无可用端口)

【问题分析】

  根据错误日志,排查出是连接数达到了最大值,(其实通过 netstat -anp|grep TIME_WAIT|wc -l也可以初略统计出当前的连接数),导致redis缓存无法使用。问题的原因是在于TIME_WAIT数量过大(会占用端口),因为每次连接断开后都会产生TIME_WAIT,这跟三次握手四次挥手有关,本质上TIME_WAIT是用于优化网络通信的。

  根据网上大部分的参考意见是修改linux的net.ipv4.tcp_tw_recycle值,说白了就是关闭了这个优化方案,虽然可行,但不建议这样处理,关闭之后可能会产生其它网络异常,虽然可能是小概率的。

  这次从产生如此多的TIME_WAIT出发点考虑。很容易发现要不就是没用连接池,要不就是连接池的参数配置跟项目差异比较大;1、对于redis缓存,使用redisgo自带的连接池,需配置MaxIdle值;2、对于数据库,自带连接池(默认可能未启用),直接调用SetMaxIdleConns设置MaxIdle值;3、对于http请求,默认没有连接池,可使用通用的go-commons-pool,通过borrow和return机制使用连接池,如有资源申请,务必记得释放;4、通过nginx转发,需在nginx.conf配置文件中增加keep alive配置。

  所有连接池都需关注idle连接数值,这个特别重要,应设置成与项目并发量相近,过低失去缓存意义,过高就是浪费。

原文地址:https://www.cnblogs.com/ftrako/p/9698942.html