生產環境發現有一些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