谢谢. 解决方案 如果您使用自动配置从属性文件定义 RDS 连接,如下所示:cloud.aws.rds.testdb.password=testdbpwdcloud.aws.rds.testdb.username=testdbusercloud.aws.rds.testdb.databaseName=testdb即使将这些(或 tomcat 数据源 conf)放入配置文件,spring boot 数据源自动配置也不起作用:spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.test-on-borrow: 真spring.datasource.validation-query: SELECT 1 FROM DUALspring.datasource.log-validation-errors: 真我认为这就是在使用连接之前无法验证池中连接的原因.您需要重写 postProcessAfterInitialization 方法来设置 TomcatJdbcDataSourceFactory bean 的池属性,如下所示:@Component公共类 PoolConfiguration 实现 BeanPostProcessor {@覆盖公共对象 postProcessAfterInitialization(Object bean, String beanName) 抛出 BeansException {如果(TomcatJdbcDataSourceFactory的bean实例){TomcatJdbcDataSourceFactory tomcatJdbcDataSourceFactory = (TomcatJdbcDataSourceFactory) bean;tomcatJdbcDataSourceFactory.setTestOnBorrow(true);tomcatJdbcDataSourceFactory.setTestWhileIdle(true);tomcatJdbcDataSourceFactory.setValidationQuery("SELECT 1");}还豆;}}我找不到任何其他解决方案.顺便说一下,这可能是 spring-cloud-aws-autoconfigure 数据包的错误.祝你好运!I have a normal spring boot 1.2.x web app with an embedded Tomcat 7.x container and connected to an RDS instance (running MySQL 5.6). If the application is idle for a period of time (8 hours?) and then it receives a request it throws the following exception** BEGIN NESTED EXCEPTION **com.mysql.jdbc.exceptions.jdbc4.CommunicationsExceptionMESSAGE: The last packet successfully received from the server was39320 seconds ago.The last packet sent successfully to the server was 39320 seconds ago, which is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.STACKTRACE:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was39320 seconds ago.The last packet sent successfully to the server was 39320 seconds ago, which is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.lang.reflect.Constructor.newInstance(Constructor.java:526)at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)... trimmed more of the stacktrace ...Caused by: java.net.SocketException: Broken pipeat java.net.SocketOutputStream.socketWrite0(Native Method)at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)at java.net.SocketOutputStream.write(SocketOutputStream.java:159)at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3227)... 119 more** END NESTED EXCEPTION **In my application.yml (where configurations for datasource, hibernate, etc. can be set) I have the following (this is part of what I get when I call the management API /env "applicationConfig: [classpath:/application.yml]#rds-profile":{ "spring.profiles":"rds-profile", "spring.datasource.driverClassName":"com.mysql.jdbc.Driver", "spring.datasource.url":"jdbc:mysql://rds-host:3306/mydb?user=mysqlusername&password=****", "spring.datasource.schema":"classpath:/schema.sql", "spring.datasource.username":"mysqlusername", "spring.datasource.password":"******", "spring.datasource.testOnBorrow":true, "spring.datasource.validationQuery":"SELECT 1", "spring.datasource.continueOnError":true, "spring.datasource.timeBetweenEvictionRunsMillis":5000, "spring.datasource.minEvictableIdleTimeMillis":5000, "spring.datasource.max-active":500, "spring.jpa.database-platform":"org.hibernate.dialect.MySQL5InnoDBDialect", "spring.jpa.database":"MYSQL", "spring.jpa.show-sql":false, "spring.jpa.generate-ddl":false, "spring.jpa.hibernate.ddl-auto":"none", "spring.jpa.hibernate.dialect":"org.hibernate.dialect.MySQL5InnoDBDialect" },Curiously, when I call the management API "/configprops" I get this (I don't know if this is the root of the problem? "spring.datasource.CONFIGURATION_PROPERTIES":{ "prefix":"spring.datasource", "properties":{ "platform":"all", "data":null, "driverClassName":"com.mysql.jdbc.Driver", "password":"******", "url":"jdbc:mysql://rds-host:3306/mydb?user=mysqlusername&password=****", "schema":"classpath:/schema.sql", "username":"mysqlusername", "jndiName":null, "xa":{ "dataSourceClassName":null, "properties":{ } }, "continueOnError":true, "sqlScriptEncoding":null, "separator":";", "initialize":true } },The question is: given the above configurations and details, why is it that I am still getting the "wait_timeout" exception? I would expect the connections to be tested when borrowed and I would expect the JDBC connection pool to create valid connections if none are available... so why is my application running out of valid connections after (8 hours?) or inactivity?Thank you. 解决方案 If you are using auto-configuration to define RDS connection from the property file like this:cloud.aws.rds.testdb.password=testdbpwdcloud.aws.rds.testdb.username=testdbusercloud.aws.rds.testdb.databaseName=testdbspring boot datasource auto-configuration will not work even you put these(or tomcat datasource conf) to your configuration file:spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.test-on-borrow: truespring.datasource.validation-query: SELECT 1 FROM DUALspring.datasource.log-validation-errors: trueI think this is the reason why you cannot validate your connections in the pool, before using them.You need to override postProcessAfterInitialization method to set pool properties of the TomcatJdbcDataSourceFactory bean like this:@Componentpublic class PoolConfiguration implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof TomcatJdbcDataSourceFactory) { TomcatJdbcDataSourceFactory tomcatJdbcDataSourceFactory = (TomcatJdbcDataSourceFactory) bean; tomcatJdbcDataSourceFactory.setTestOnBorrow(true); tomcatJdbcDataSourceFactory.setTestWhileIdle(true); tomcatJdbcDataSourceFactory.setValidationQuery("SELECT 1"); } return bean;}}I could not find any other solution for this.By the way this might be a bug of spring-cloud-aws-autoconfigure packet.Good Luck! 这篇关于一段时间后,spring-boot Web 应用程序失去连接到 MySQL/RDS 的能力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-04 13:43
查看更多