
我的伺服器開始每天至少掛起一次。直到我重新啟動 Tomcat 為止,情況仍然如此。我還不確定哪個部分導致了問題,所以我嘗試研究幾個假設:
- 我的網站透過 Google 的 PageSpeed 提供服務,因此我懷疑我是否受到了 DDoS 攻擊。
- 當它掛起時,我必須重新啟動 apache2 和 tomcat。所以我無法判斷是哪一個導致了問題。
- 當伺服器掛起時,我檢查mysql的進程列表,發現有十幾個空閒連線。這意味著資料庫沒有過載。
當伺服器掛起時,我很少看到像這樣的錯誤。因此,問題可能出在我的 Java 程式碼和 MySQL 之間的連線:
java.sql.SQLException: Operation not allowed after ResultSet closed at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:924) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:870) at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:734) at com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:778) at com.mysql.jdbc.ResultSetImpl.getObject(ResultSetImpl.java:4419) at com.mypackage.SqlUtils.getResultMapList(SqlUtils.java:66)
我用於從資料庫檢索結果的集中程式碼是:
public List<ResultMap> getResultMapList(String sql) {
List<ResultMap> rows = new LinkedList<>();
try (Connection conn = getConnection();
ResultSet res = conn.createStatement().executeQuery(sql)) {
while (res.next()) {
ResultMap row = new ResultMap();
ResultSetMetaData meta = res.getMetaData();
for (int i = 1; i <= meta.getColumnCount(); i++) {
row.put(meta.getColumnLabel(i).toLowerCase(), res.getObject(i)); // Line 66
}
rows.add(row);
}
} catch (Exception e) {
e.printStackTrace();
}
return rows;
}
我的連結是池化的:
public Connection getConnection() {
if (datasource == null) {
PoolProperties p = new PoolProperties();
p.setUrl(myURL);
p.setDriverClassName("com.mysql.jdbc.Driver");
p.setUsername(dbprefix + "user1");
p.setPassword(password);
p.setJmxEnabled(true);
p.setTestWhileIdle(false);
p.setTestOnBorrow(true);
p.setValidationQuery("SELECT 1");
p.setTestOnReturn(false);
p.setValidationInterval(30000);
p.setTimeBetweenEvictionRunsMillis(1000);
p.setMaxActive(20);
p.setMaxIdle(5);
p.setInitialSize(5);
p.setMaxWait(10000);
p.setRemoveAbandonedTimeout(30);
p.setMinEvictableIdleTimeMillis(10000);
p.setMinIdle(2);
p.setLogAbandoned(true);
p.setRemoveAbandoned(true);
p.setFairQueue(true);
p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
datasource = new DataSource();
datasource.setPoolProperties(p);
}
Connection conn = null;
try {
conn = datasource.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
ResultMap
extends LinkedHashMap<String, Object>
,我只使用它來儲存在 .extends 中檢索到的欄位ResultSet
。
安裝的軟體:Apache/2.4.7(Ubuntu)、Mysql:5.5.40(InnoDB)、Tomcat:8.0.15、Java:1.8.0_25。
關於伺服器掛起的原因有什麼建議嗎?
答案1
也許是logrotate,它正在重新啟動mysql,然後您與資料庫的連線需要關閉+重新開啟?