Java Spring数据、MySQL连接在8小时不活动后终止

Java Spring数据、MySQL连接在8小时不活动后终止,java,spring,hibernate,spring-data,Java,Spring,Hibernate,Spring Data,我面临一个问题,在一段时间的不活动之后,我的数据源bean将崩溃。我的问题是如何重新实例化在应用程序启动时遇到的数据源bean 下面是我们如何在启动时设置bean @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource dataSource(){ byte[] encryptedFile = fileRetriever.getFile(bucket, key); String u

我面临一个问题,在一段时间的不活动之后,我的数据源bean将崩溃。我的问题是如何重新实例化在应用程序启动时遇到的数据源bean

下面是我们如何在启动时设置bean

@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource dataSource(){
    byte[] encryptedFile = fileRetriever.getFile(bucket, key);
    String unencryptedJson = fileDecrypter.decryptFile(encryptedFile);
    JSONParser parser = new JSONParser();
    JSONObject jsonObject = null;
    try{
        jsonObject = (JSONObject) parser.parse(unencryptedJson);
    }catch (Exception ex){
        log.error(ex.getMessage());
    }

    String password = (String)jsonObject.get("password");

    DataSource ds = DataSourceBuilder
            .create()
            .url(url)
            .username(userName)
            .password(password)
            .build();

    return ds;

}
此类上还有一个
@配置
注释

我们还有其他没有这个问题的应用程序,这些应用程序在不活动后需要跳转服务,但它们也没有以这种方式设置数据源,并且在
application.property
文件中指定了所有详细信息

我添加了一个自定义的运行状况检查,它使用一个存储库,该存储库每30秒运行一次,这样应该可以使数据源bean保持活动状态,但如果它确实发生故障,我需要一种方法来重新创建它


提前感谢

可能会被认为是池数据源连接器。看看apachedbcb2

下面是我的一个示例,它至少保持10个空闲,并根据需要从池中增加

private static DataSource createDataSource(String url, String userName, String passwrd) throws Exception {
    Class.forName(DRIVER).newInstance();

    Properties props = new Properties();
    props.setProperty("user", userName);
    props.setProperty("password", passwrd);

    //Create a connection factory that the pool will use to create connections
    ConnectionFactory cf = new DriverManagerConnectionFactory(url, props);
    //Create the poolable connection factory 
    PoolableConnectionFactory pcf = new PoolableConnectionFactory(cf, null);
    pcf.setValidationQuery("SELECT 1");
    pcf.setDefaultAutoCommit(true);

    GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
    poolConfig.setMinIdle(10);
    poolConfig.setMaxTotal(100);

    AbandonedConfig abandonConfig = new AbandonedConfig();
    abandonConfig.setRemoveAbandonedTimeout(60);
    abandonConfig.setLogAbandoned(false);
    abandonConfig.setRemoveAbandonedOnBorrow(true);
    abandonConfig.setRemoveAbandonedOnMaintenance(true);

    //Create the pool of connections
    GenericObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(pcf, poolConfig);
    connectionPool.setTestOnBorrow(true);
    connectionPool.setTestWhileIdle(true);
    connectionPool.setTimeBetweenEvictionRunsMillis(10000);
    connectionPool.setMinEvictableIdleTimeMillis(1000);
    connectionPool.setAbandonedConfig(abandonConfig);
    pcf.setPool(connectionPool);

    //Pooling data source itself
    PoolingDataSource<PoolableConnection> dataSource = new PoolingDataSource<>(connectionPool);
    return dataSource;
  }
私有静态数据源createDataSource(字符串url、字符串用户名、字符串passwrd)引发异常{
Class.forName(DRIVER.newInstance();
Properties props=新属性();
props.setProperty(“用户”,用户名);
props.setProperty(“密码”,passwrd);
//创建池将用于创建连接的连接工厂
ConnectionFactory cf=新的驱动程序管理器ConnectionFactory(url,道具);
//创建可池连接工厂
PoolableConnectionFactory pcf=新的PoolableConnectionFactory(cf,null);
pcf.setValidationQuery(“选择1”);
pcf.setDefaultAutoCommit(真);
GenericObjectPoolConfig-poolConfig=新的GenericObjectPoolConfig();
poolConfig.setMinIdle(10);
poolConfig.setMaxTotal(100);
放弃配置放弃配置=新建放弃配置();
放弃配置setRemoveBandonedTimeout(60);
放弃Config.SetLogForwarded(false);
放弃配置setRemoveBandoneBrow(true);
放弃配置setRemoveBandonMaintenance(true);
//创建连接池
GenericObjectPool connectionPool=新的GenericObjectPool(pcf,poolConfig);
connectionPool.settstonbrow(true);
connectionPool.setTestWhileIdle(true);
connectionPool.setTimeBetweenEvictionRunsMillis(10000);
连接池。setminevictableidletimillis(1000);
connectionPool.setAbundedConfig(放弃配置);
pcf.setPool(connectionPool);
//池化数据源本身
PoolgDataSource数据源=新的PoolgDataSource(connectionPool);
返回数据源;
}
ApacheDBCB2的Maven依赖项

        <!-- Database connection pools -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.4.2</version>
        </dependency>

org.apache.commons
commons-dbcp2
2.1.1
org.apache.commons
commons-pool2
2.4.2

我假设boot正在为您配置数据源。在本例中,由于您使用的是MySQL,您可以将以下内容添加到application.properties中,直到1.3

spring.datasource.test-on-borrow=true
spring.datasource.validationQuery=SELECT 1

在空闲时尝试测试=真。这样你的空闲连接将始终处于活动状态。这不是最好的主意,但你可以每5-8小时轮询一次数据库以保持连接的活动状态。我认为这里的想法是保持空闲连接的活动状态。频率可以是分钟或小时,具体取决于需要。理想情况下,在生产环境中,空闲时间不超过8小时,但如果是,我需要能够为数据源重新创建bean。因此,我尝试了这一点,但仍然不走运,因为我正在设置bean,因为密码存储在AWS KMS中,这不像我在application.property文件中指定了所有详细信息一样,ConnectionFactory在哪个库中?
org.apache.commons.dbcb2
是apache dbcb2库的包。我在回答中添加了maven依赖项(如果您使用的是maven)