Quartz 调度程序不会在 AWS RDS 故障转移时更新数据库连接
Quartz scheduler does not renew DB connections on AWS RDS failover
我们将 Java Quartz 调度程序与 AWS RDS Aurora 集群一起用作底层数据存储。 RDS 配置为具有一个主 read/write 数据库和一个只读副本的集群。
当我在 AWS RDS 控制台中单击 "Instance Actions > Failover" 时,当前写入器变为 reader,只读副本变为写入器。
但是在那种情况下,Quartz JDBC DataSource/Connection 池似乎无法处理故障转移并且调度程序因以下错误而终止:
2018-08-22 13:10:21.106 ERROR 14824 --- [_ClusterManager] org.quartz.impl.jdbcjobstore.JobStoreTX : ClusterManager: Error managing cluster: Failure updating scheduler state when checking-in: The MySQL server is running with the --read-only option so it cannot execute this statement
org.quartz.JobPersistenceException: Failure updating scheduler state when checking-in: The MySQL server is running with the --read-only option so it cannot execute this statement
at org.quartz.impl.jdbcjobstore.JobStoreSupport.clusterCheckIn(JobStoreSupport.java:3468)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.doCheckin(JobStoreSupport.java:3315)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.manage(JobStoreSupport.java:3920)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.run(JobStoreSupport.java:3957)
Caused by: java.sql.SQLException: The MySQL server is running with the --read-only option so it cannot execute this statement
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:127)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:960)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1116)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1066)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1396)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1051)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:384)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.updateSchedulerState(StdJDBCDelegate.java:2975)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.clusterCheckIn(JobStoreSupport.java:3462)
... 3 common frames omitted
quartz.properties配置如下
org.quartz.dataSource.quartzDataSource.driver=com.mysql.cj.jdbc.Driver
org.quartz.dataSource.quartzDataSource.URL=jdbc:mysql://sqldbprd...:3306/quartz?useSSL=false
org.quartz.dataSource.quartzDataSource.user=quartz
org.quartz.dataSource.quartzDataSource.password=...
org.quartz.dataSource.quartzDataSource.maxConnections=5
org.quartz.dataSource.quartzDataSource.validationQuery=SELECT 1
org.quartz.dataSource.quartzDataSource.TestConnectionOnCheckin=false
org.quartz.dataSource.quartzDataSource.TestConnectionOnCheckout=true
相反,我们使用默认 HikariCP 配置的主要 Spring 引导 API 继续工作,似乎选择了 writer/reader 开关。
有没有人也遇到过这种情况?可以将 Quartz 配置为使用(现有的)HikariCP 而不是创建自己的 DataSource/Pool 吗?任何建议表示赞赏!
我在连接到 Aurora postgres 的 spring 引导应用程序时遇到了同样的问题。
JVM 缓存 DNS 并在故障转移后引用旧的(现在 reader)实例。
您可以通过将以下行放入应用程序的启动来将缓存设置为不同的值:
java.security.Security.setProperty("networkaddress.cache.ttl", "60");
我们遇到的另一个问题是我们不小心将数据库的实例 url 而不是集群 url。
更多信息:https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-jvm-ttl.html
我们将 Java Quartz 调度程序与 AWS RDS Aurora 集群一起用作底层数据存储。 RDS 配置为具有一个主 read/write 数据库和一个只读副本的集群。
当我在 AWS RDS 控制台中单击 "Instance Actions > Failover" 时,当前写入器变为 reader,只读副本变为写入器。
但是在那种情况下,Quartz JDBC DataSource/Connection 池似乎无法处理故障转移并且调度程序因以下错误而终止:
2018-08-22 13:10:21.106 ERROR 14824 --- [_ClusterManager] org.quartz.impl.jdbcjobstore.JobStoreTX : ClusterManager: Error managing cluster: Failure updating scheduler state when checking-in: The MySQL server is running with the --read-only option so it cannot execute this statement
org.quartz.JobPersistenceException: Failure updating scheduler state when checking-in: The MySQL server is running with the --read-only option so it cannot execute this statement
at org.quartz.impl.jdbcjobstore.JobStoreSupport.clusterCheckIn(JobStoreSupport.java:3468)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.doCheckin(JobStoreSupport.java:3315)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.manage(JobStoreSupport.java:3920)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.run(JobStoreSupport.java:3957)
Caused by: java.sql.SQLException: The MySQL server is running with the --read-only option so it cannot execute this statement
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:127)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:960)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1116)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1066)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1396)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1051)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:384)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.updateSchedulerState(StdJDBCDelegate.java:2975)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.clusterCheckIn(JobStoreSupport.java:3462)
... 3 common frames omitted
quartz.properties配置如下
org.quartz.dataSource.quartzDataSource.driver=com.mysql.cj.jdbc.Driver
org.quartz.dataSource.quartzDataSource.URL=jdbc:mysql://sqldbprd...:3306/quartz?useSSL=false
org.quartz.dataSource.quartzDataSource.user=quartz
org.quartz.dataSource.quartzDataSource.password=...
org.quartz.dataSource.quartzDataSource.maxConnections=5
org.quartz.dataSource.quartzDataSource.validationQuery=SELECT 1
org.quartz.dataSource.quartzDataSource.TestConnectionOnCheckin=false
org.quartz.dataSource.quartzDataSource.TestConnectionOnCheckout=true
相反,我们使用默认 HikariCP 配置的主要 Spring 引导 API 继续工作,似乎选择了 writer/reader 开关。
有没有人也遇到过这种情况?可以将 Quartz 配置为使用(现有的)HikariCP 而不是创建自己的 DataSource/Pool 吗?任何建议表示赞赏!
我在连接到 Aurora postgres 的 spring 引导应用程序时遇到了同样的问题。
JVM 缓存 DNS 并在故障转移后引用旧的(现在 reader)实例。 您可以通过将以下行放入应用程序的启动来将缓存设置为不同的值:
java.security.Security.setProperty("networkaddress.cache.ttl", "60");
我们遇到的另一个问题是我们不小心将数据库的实例 url 而不是集群 url。
更多信息:https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-jvm-ttl.html