服務器環境:centos6.7 + tomcat7.0.69 + jdk1.7.0_55 + mysql5.6.28
場景:服務剛開始用戶體驗變差,請求時間長,之后出現404,500等與服務器交互失敗問題。重啟后用戶體驗回升,半小時內問題沒有再現。
日志中出現的問題有兩個:
1、Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
2、Mar 06, 2017 10:59:53 AM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
SEVERE: Socket accept failed
java.net.SocketException: Too many open files
解決方案:
1、更改centos的單個文件最大句柄數為最大的65535,tomcat宕機的直接原因是 第二個問題 Too many open files
2、更改線程池的配置增加如下參數:
- maxWait="3000" 從池中取連接的最大等待時間,單位ms.
- initialSize="10" 初始化連接
- minIdle="10" 最小空閑連接
- maxIdle="150" 最大空閑連接
- maxActive="200" 最大活動連接
- validationQuery = "SELECT 1" 驗證使用的SQL語句
- testWhileIdle = "true" 指明連接是否被空閑連接回收器(如果有)進行檢驗.如果檢測失敗,則連接將被從池中去除.
- testOnBorrow = "false" 借出連接時不要測試,否則很影響性能
- timeBetweenEvictionRunsMillis = "30000" 每30秒運行一次空閑連接回收器
- minEvictableIdleTimeMillis = "1800000" 池中的連接空閑30分鍾后被回收
- numTestsPerEvictionRun="10" 在每次空閑連接回收器線程(如果有)運行時檢查的連接數量
- removeAbandoned="true" 連接泄漏回收參數,當可用連接數少於3個時才執行
- removeAbandonedTimeout="180" 連接泄漏回收參數,180秒,泄露的連接可以被刪除的超時值
問題原因:
1、網絡延遲增加;
2、tomcat的dbcp線程池設置偏小,當請求突發的時候出現線程池報錯;
3、同時,由於對服務的請求及服務向數據庫發起的服務的增加,在突發情況中擊穿數據庫限制超出最大句柄數
4、導致進程掛死。
原因分析過程:
一、分析服務的系統日志,獲取報錯種類及第一次發生的時間節點
二、分析服務的系統日志,查獲所有數據庫訪問請求的執行時間點,服務的請求時間;
三、統計每一秒內的數據庫請求總數量,各個請求的總數量,各個請求失敗總數量
四、分析數據庫日志,獲取處理時間長及失敗的SQL語句的執行時間及處理時長
五、對比三和四步驟的結果初略的判斷是否存在網絡問題
其中頻繁使用的小技巧:
1、notepad++的正則查找:
a、搜索的設置如下圖:
b、使用正則查找行中有10.6.6.5或Query_time或order by c.isTop DESC 三個字段的行
^.*10\.6\.6\.5.*$|^.*Query\_time.*$|^.*order by c\.isTop DESC\, c\.id asc.*$
2、excel中的vlookup公式,篩選、分列、多列排序、分類匯總、Ctrl+G>定點條件>可見單元格、插入圖表