最近线上的mongo出现了连接数报警,登上去查看后,发现连接数上去之后一直没有降下来,而很多会话都处于「不活跃」状态。

最开始是想是不是因为程序已经重启了,产生了新连接,而mongo服务端一直保持着旧连接没有释放。但通过对比连接数上涨的时间,已经过去蛮久了,作为TCP连接,假设一方连接已经中断,mongo服务端这时候理应也要释放了。

所以只能是:这些不活跃会话接其实还是保持着连接。
通过这个思路,最终找到了原因,客户端连接池的空闲连接一直没有释放。

mongo go driver的连接池,主要有这么几项设置:

1
2
3
4
5
6
7
type poolConfig struct {
Address address.Address
MinPoolSize uint64
MaxPoolSize uint64
MaxIdleTime time.Duration
PoolMonitor *event.PoolMonitor
}

这次最主要的关注点就在MaxIdleTime,它代表着连接最大空闲时间。由于之前的使用当中并没有特意去配置,所以使用了默认配置,相当于没有限制。

另外还有PoolSize的设置,默认MaxPoolSize是100,也就是说,如果没有配置超时时间,一个连接池就有可能握住100个连接永不释放。

针对上面的空闲连接没有释放问题,很简单,我们只需要根据业务场景,考虑是否需要加上连接的最大空闲时间即可,比如1小时,半小时。

参考

mongo-go-driver/pool.go at master · mongodb/mongo-go-driver · GitHub