connection pool exhausted


1.發現問題

生產環境發現有一些redis報錯日志 connection pool exhausted。如果redis中沒有數據 就直接回源 查DB。暫時不會有什么大問題。中文意思是連接池耗盡。

2.追蹤問題

查看源碼

我們用的redis客戶端類似於redigo 按照錯誤提示搜索到了一段代碼(基於最新的redigo 源碼版本分析)

   // Handle limit for p.Wait == false.
   if !p.Wait && p.MaxActive > 0 && p.active >= p.MaxActive {
   	p.mu.Unlock()
   	return nil, ErrPoolExhausted
   }

源碼解析

這段代碼的意思是 如果沒有配置為等待模式。且配置了連接池的最大活躍個數 如果當前活躍個數大於配置的最大活躍 則返回連接池耗盡的錯誤。所以需要調大這個MaxActive參數。

MaxIdle 參數

除了MaxActive 之外還有一個MaxIdle參數。

   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,就會把尾部的連接刪除 把最新的連接放到頭部。類似將老的連接刪掉,加入最新的。

3.解決問題

最終通過調大 MaxActive 和 MaxIdle 參數解決了連接池耗盡的問題

4. docker環境實驗源碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM