生产环境发现有一些redis报错日志 connection pool exhausted。若是redis中没有数据 就直接回源 查DB。暂时不会有什么大问题。中文意思是链接池耗尽。
咱们用的redis客户端相似于redigo 按照错误提示搜索到了一段代码(基于最新的redigo 源码版本分析)git
// Handle limit for p.Wait == false. if !p.Wait && p.MaxActive > 0 && p.active >= p.MaxActive { p.mu.Unlock() return nil, ErrPoolExhausted }
这段代码的意思是 若是没有配置为等待模式。且配置了链接池的最大活跃个数 若是当前活跃个数大于配置的最大活跃 则返回链接池耗尽的错误。因此须要调大这个MaxActive参数。github
除了MaxActive 以外还有一个MaxIdle参数。golang
func (p *Pool) put(pc *poolConn, forceClose bool) error { p.mu.Lock() if !p.closed && !forceClose { pc.t = nowFunc() p.idle.pushFront(pc) if p.idle.count > p.MaxIdle { pc = p.idle.back p.idle.popBack() } else { pc = nil } } if pc != nil { p.mu.Unlock() pc.c.Close() p.mu.Lock() p.active-- } if p.ch != nil && !p.closed { p.ch <- struct{}{} } p.mu.Unlock() return nil }
链接池的具体实现是经过一个链表来实现的。若是发现链接池里面的空闲个数超过了MaxIdle,就会把尾部的链接删除 把最新的链接放到头部。相似将老的链接删掉,加入最新的。redis
最终经过调大 MaxActive 和 MaxIdle 参数解决了链接池耗尽的问题docker