我的服务器每天至少挂起一次。除非我重新启动 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
扩展LinkedHashMap<String, Object>
,并且我仅使用它来存储在中检索到的字段ResultSet
。
安装的软件:Apache/2.4.7(Ubuntu)、Mysql:5.5.40(InnoDB)、Tomcat:8.0.15、Java:1.8.0_25。
关于服务器挂起的原因,有什么建议吗?
答案1
也许是 logrotate,它正在重新启动 mysql,然后需要关闭+重新打开与数据库的连接?