【发布时间】:2021-03-17 04:52:19
【问题描述】:
我有一个使用 Tomcat 8.5 连接池、Java 8 和多可用区 AWS RDS MySQL 数据库的应用程序。在过去几年中,我们遇到了几个导致故障转移的数据库问题。发生故障转移时,池始终能够检测到连接已关闭(连接关闭后不允许任何操作),并在备份节点启动后一分钟后正确重新连接。
几天前,我们进行了一次未遵循此规则的故障转移。由于硬件数据库问题,数据库不可用并且发生了故障转移。然后,几分钟后,当备份节点启动时,我们可以从桌面 MySQL 客户端正确连接到数据库。
即使在发生故障转移并恢复与数据库的连接后几分钟,应用程序仍会显示数百个异常日志,例如:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed
...
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
...
The last packet successfully received from the server was 20,017 milliseconds ago. The last packet sent successfully to the server was 20,016 milliseconds ago
...
Caused by: java.net.SocketTimeoutException: Read timed out
...
在我们重新启动 Tomcat 服务器之前,应用程序无法重新连接。
我们的池是这样配置的:
initialSize = 5
maxActive = 16
minIdle = 5
maxIdle = 8
maxWait = 10000
maxAge = 600000
timeBetweenEvictionRunsMillis = 5000
minEvictableIdleTimeMillis = 60000
validationQuery = "SELECT 1"
validationQueryTimeout = 3
validationInterval = 15000
testOnBorrow = true
testWhileIdle = true
testOnReturn = false
jdbcInterceptors = "ConnectionState;StatementCache(max=200)"
defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
而 JDBC 连接 URL 有这些参数:
autoreconnect=true&socketTimeout=20000
根据我的理解,validationQuery 应该已经失败并且连接被丢弃,所以应该已经创建了一个新的正确连接。此外,根据maxAge,10 分钟后所有连接都应该被丢弃并创建新连接。
即使在 20 分钟后也无法恢复池。如前所述,我们必须重新启动 Tomcat 服务器。
有什么解释为什么池总是从故障转移中正确恢复,但在这种情况下,它不能?
【问题讨论】:
标签: mysql jdbc amazon-rds tomcat-jdbc