我有一个使用Tomcat8.5连接池、Java8和Multi-AZ 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_COMMITTEDJDBC连接URL具有以下参数:
autoreconnect=true&socketTimeout=20000
根据我的理解,validationQuery应该已经失败并且连接被丢弃,所以应该已经创建了一个新的正确的连接。此外,根据maxAge的说法,在10分钟后,所有连接都应该被丢弃并创建新的连接。
即使在20分钟后,池也无法恢复。如上所述,我们必须重新启动Tomcat服务器。
为什么池总是能从故障转移中正确恢复,但在这种情况下却无法恢复,有什么解释吗?
发布于 2020-12-10 23:53:48
我最终添加了一个AWS RDS代理来解决这个问题。
我已经触发DB Failover一个小时了,一切正常,停机时间不到20秒。这样,在不修改我的应用程序代码的情况下,只指向新的代理端点。
发布于 2020-12-06 21:03:14
尝试在连接字符串中添加ENABLE=Broken。例如: jdbc:oracle:thin:@(DESCRIPTION=(ENABLE=BROKEN)(ADDRESS=(PROTOCOL=tcp)(PORT=)(HOST=))(CONNECT_DATA=(SID=)))
https://stackoverflow.com/questions/65155359
复制相似问题