经过一定时间后,带有ThreadPoolTask​​Executor的Spring Boot应用程序将失去与mysql的连接

时间:2019-02-14 13:34:39

标签: java mysql spring-boot

我在解决现有Spring Boot应用程序中的问题时遇到麻烦。应用程序已使用“ ThreadPoolTask​​Executor”进行配置的地方。并在某些时间后通过抛出“ MySQLNonTransientConnectionException”异常而失去与mysql的数据库连接。

请在我试图分析问题的地方找到以下应用程序详细信息-

springBootVersion:1.5.2 Groovy版本:2.3.9

  1. 已在WebAppConfig.groovy中配置了以下Bean
@Bean
HealthCheckRegistry healthCheckRegistry(@Qualifier("dataSource") DataSource rlOpDataSource) {
    def dBCheck = new BasicDatabaseCheck(dataSource, true)
    Map<String, HealthCheck> healthCheckMap = ["Database Check":dBCheck]
    HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry(healthCheckExecutor(), healthCheckMap)
    healthCheckRegistry
}

@Bean
AsyncTaskExecutor healthCheckExecutor() {
    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor()
    threadPoolTaskExecutor.with {
        corePoolSize = Runtime.getRuntime().availableProcessors() * 2
        maxPoolSize = Integer.MAX_VALUE
        queueCapacity = Integer.MAX_VALUE
        keepAliveSeconds = 60
        allowCoreThreadTimeOut = true
    }
    threadPoolTaskExecutor.initialize()
    new ConcurrentTaskExecutor(threadPoolTaskExecutor)
}
  1. BasicDatabaseCheck类具有JdbcTemplate实例
public class BasicDatabaseCheck  {
    private JdbcTemplate jdbcTemplate;

    public BasicDatabaseCheck(DataSource dataSource) {
        this(new JdbcTemplate(dataSource), isPrimary);
    }

    public HealthState execute() {
    ---(implementation which executes database queries using 
    JdbcTemplate)
    }
}
  1. HealthCheckRegistry,它通过以下方式调用BasicDatabaseCheck函数 AsyncTaskExecutor
HealthCheckRegistry class with :

    public class HealthCheckRegistry {

    private final AsyncTaskExecutor executor;

    public HealthCheckResults runHealthChecks{

    Future<HealthState> future = this.executor.submit(
    ----(implementation which calls BasicDatabaseCheck.execute function)
                });
} 

使用此配置,应用程序可以正常运行。公开了其他api,这些api也毫无例外。但是一段时间后,应用程序将引发以下错误:

 WARN 24566 --- [ThreadPoolTaskExecutor-1] o.s.jdbc.support.SQLErrorCodesFactory    : Error while extracting database name - falling back to empty error codes

org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:342) ~[spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366) ~[spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:212) ~[spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:134) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:97) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:419) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:474) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:484) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:494) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.queryForMap(JdbcTemplate.java:489) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at com.reachlocal.health.impl.BasicDatabaseCheck.execute(BasicDatabaseCheck.java:38) [core-2.0.jar!/:na]
    at com.reachlocal.health.HealthCheckRegistry$1.call(HealthCheckRegistry.java:139) [core-2.0.jar!/:na]
    at com.reachlocal.health.HealthCheckRegistry$1.call(HealthCheckRegistry.java:135) [core-2.0.jar!/:na]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_25]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_25]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_25]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_25]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408) ~[na:1.8.0_25]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:389) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.Util.getInstance(Util.java:372) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:958) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:937) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:872) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1236) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1231) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.java:2938) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.java:2933) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) ~[tomcat-jdbc-8.5.11.jar!/:na]
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) ~[tomcat-jdbc-8.5.11.jar!/:na]
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81) ~[tomcat-jdbc-8.5.11.jar!/:na]
    at com.sun.proxy.$Proxy102.getMetaData(Unknown Source) ~[na:na]
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:331) ~[spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    ... 17 common frames omitted
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 4,825 milliseconds ago.  The last packet sent successfully to the server was 602 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_25]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_25]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_25]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408) ~[na:1.8.0_25]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:389) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1038) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3422) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3322) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3762) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2531) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2489) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1446) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at org.springframework.jdbc.core.JdbcTemplate$1QueryStatementCallback.doInStatement(JdbcTemplate.java:458) ~[spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:408) [spring-jdbc-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
    ... 11 common frames omitted
Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:189) ~[na:1.8.0_25]
    at java.net.SocketInputStream.read(SocketInputStream.java:121) ~[na:1.8.0_25]
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:100) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:143) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:173) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2911) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3332) ~[mysql-connector-java-5.1.35.jar!/:5.1.35]
    ... 20 common frames omitted

我尝试了以下解决方案:

  1. 将mysql连接器jar从5.1.6更新为5.1.35
  2. mysql关闭数据库连接的可能原因之一 理想时间后超过8小时(默认设置)。所以我加了一个 调度函数,调用HealthCheckRegistry的execute函数 每1小时递归递归。之后提到的发生 异常开始不一致。

因此,请任何人可以帮助我解决问题..?

0 个答案:

没有答案