如何为 Elastic Beanstalk 应用程序正确配置 Spring 数据源?

How to properly configure Spring Datasource for an Elastic Beanstalk app?

我正在 运行 解决将 Spring 安全与我的 Elastic Beanstalk 应用程序集成的问题,该应用程序由 MySql 数据库支持。如果我部署我的应用程序,我可以在一段时间内正确登录,但最终我会开始收到登录错误,而且不会抛出异常,因此我无法获得有关该问题的任何有用信息。我也下载了日志,但看不到任何有价值的东西。我可以看到日志显示访问 public 页面的位置,尝试访问私有部分,返回登录页面,然后是 loginError 页面;但是,没有任何问题。

即使我无法通过浏览器登录,但如果我从 IDE 运行 应用程序以及查看 MySQL 中的数据库,我仍然可以登录 Workbench。这向我表明问题是由于服务器上的某些持久状态引起的。

我之前在另一个使用 Spring 安全性的 Beanstalk 应用程序中遇到过类似的问题,并且能够通过如下设置应用程序属性来解决它:

spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1

我使用的 Spring 版本比该应用更新,并且属性已更改为特定数据源,因此我尝试添加以下属性:

spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.validation-query=SELECT 1

当这不起作用时,我根据对此处类似问题的回答添加了另一个;现在属性是:

spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.test-while-idle=true
spring.datasource.tomcat.validation-query=SELECT 1

这似乎可行(可能是由于登录较少 activity),但最终导致了相同的行为。

我研究了各种 properties available 但在我花很多时间随机设置 and/or 覆盖默认设置之前,我想看看是否有可靠的方法来处理这个问题。

如何配置我的数据源以避免长时间登录错误?

这不是特定配置值的问题,而是这些配置所在位置的问题。 application.properties (/resources; Intellij) 的默认位置适合部署为带有嵌入式 Tomcat 服务器的 jar,但不适用于带有提供的服务器的 war。该文件不是 found/used,因此对文件的更改不会影响 AWS 给出的文件。

有多种方法可以解决这个问题;我选择在 SpringBootServletInitializer:

中添加一个 RDS 配置 bean
@Bean
public RdsInstanceConfigurer instanceConfigurer() {
    return () -> {
        TomcatJdbcDataSourceFactory dataSourceFactory =
                new TomcatJdbcDataSourceFactory();
        // Abondoned connections...
        dataSourceFactory.setRemoveAbandonedTimeout(60);
        dataSourceFactory.setRemoveAbandoned(true);
        dataSourceFactory.setLogAbandoned(true);
        // Tests
        dataSourceFactory.setTestOnBorrow(true);
        dataSourceFactory.setTestOnReturn(false);
        dataSourceFactory.setTestWhileIdle(false);
        // Validations
        dataSourceFactory.setValidationInterval(30000);
        dataSourceFactory.setTimeBetweenEvictionRunsMillis(30000);
        dataSourceFactory.setValidationQuery("SELECT 1");
        return dataSourceFactory;
    };
}

以下是对我有用的设置。 来自

dataSourceFactory.setMaxActive(10);
dataSourceFactory.setInitialSize(10);
dataSourceFactory.setMaxIdle(10);
dataSourceFactory.setMinIdle(1);
dataSourceFactory.setTestWhileIdle(true);
dataSourceFactory.setTestOnBorrow(true);
dataSourceFactory.setValidationQuery("SELECT 1 FROM DUAL");
dataSourceFactory.setValidationInterval(10000);
dataSourceFactory.setTimeBetweenEvictionRunsMillis(20000); 
dataSourceFactory.setMinEvictableIdleTimeMillis(60000);