connection pool exhausted

1.發現問題

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

2.追蹤問題

查看源碼

咱們用的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

MaxIdle 參數

除了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

3.解決問題

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

4. docker環境實驗源碼

相關文章
相關標籤/搜索