平時工作用數據庫連接池的時候,有時候會遇見超時獲取不到的報錯:
Connection is not available, request timed out after XXms.
但是,並不能一下子看出什么問題導致,因為可能性有蠻多:
1. 可能是真的連接池負載高了
這種情況,連接數達到最大連接數,並且所有連接都處於 active 狀態, 一般有2個原因
1.1 流量突增
初步判斷:qps 突增,大大超過原預估的連接池容量需求
進一步判斷:
- 前端業務做活動(比如營銷活動)沒有告知后端/平台服務?
- soa 流量傾斜到某個機器?
- ...
1.2 處理變慢
處理變慢,連接歸還連接池就慢,單位時間一個連接處理的請求數就降低
初步判斷:sql耗時曲線增高
進一步判斷: 這種情況會負載些 要綜合看各項指標
- 可能是 機器fullgc了
- cpu、io抖動了
- 存在慢sql
- db抖動
- 數據庫事務死鎖
- 。。。
2. 連接建立失敗
當然,有可能你發現連接池還沒達到最大連接數,但是就是超時獲取不到; 這時候很大的概率是db 連不上了,或者 機器和db之間的網絡存在問題
這種比較好判斷:可以進一步從報錯堆棧中檢查,是 socket timeout 還是其他什么具體原因
總結
同一個報錯,可能有各種各樣的原因,不要急於歸結於一個點,要綜合、客觀地分析各種現象;
同時,建立完善的監控、埋點,以便快速收集客觀、全面、時間遞進的數據幫助排障; 比如第一類原因, 沒有監控圖標、沒有曲線圖,就需要你具備老道的經驗,還得一個個的去檢查,才能最后定位根因