mysql - ejemplo - spring boot jpa
la aplicaciĆ³n web spring-boot pierde la capacidad de conectarse a MySQL/RDS despuĆ©s de un tiempo (2)
Trata de usar esto también
spring.datasource.test-while-idle=true
spring.datasource.validation-interval=5000
Tengo una aplicación web de arranque de primavera normal 1.2.x con un contenedor integrado Tomcat 7.x y conectado a una instancia de RDS (ejecutando MySQL 5.6). Si la aplicación está inactiva durante un período de tiempo (8 horas?) Y luego recibe una solicitud arroja la siguiente excepción
** BEGIN NESTED EXCEPTION **
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
MESSAGE: The last packet successfully received from the server was39320 seconds ago.The last packet sent successfully to the server was 39320 seconds ago, whi
ch is longer than the server configured value of ''wait_timeout''. You should consider either expiring and/or testing connection validity before use in your ap
plication, increasing the server configured values for client timeouts, or using the Connector/J connection property ''autoReconnect=true'' to avoid this proble
m.
STACKTRACE:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was39320 seconds ago.The last packet sent succe
ssfully 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 t
esting connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection pr
operty ''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 pipe
at 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 **
En mi application.yml (donde se pueden configurar configuraciones para datasource, hibernate, etc.) tengo lo siguiente (esto es parte de lo que obtengo cuando llamo a la API / env de administración
"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"
},
Curiosamente, cuando llamo a la API de gestión "/ configprops" obtengo esto (no sé si esta es la raíz del problema).
"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
}
},
La pregunta es: dada la configuración y los detalles anteriores, ¿por qué sigo recibiendo la excepción "wait_timeout"? Esperaría que las conexiones se prueben cuando se presten y esperaría que el conjunto de conexiones JDBC creara conexiones válidas si ninguna está disponible ... entonces ¿por qué mi aplicación se queda sin conexiones válidas después de (8 horas?) O inactividad?
Gracias.
Si está utilizando la configuración automática para definir la conexión RDS desde el archivo de propiedades como este:
cloud.aws.rds.testdb.password=testdbpwd
cloud.aws.rds.testdb.username=testdbuser
cloud.aws.rds.testdb.databaseName=testdb
la configuración automática del origen de datos de arranque de primavera no funcionará incluso si usted pone estos (o conf de origen de datos tomcat) en su archivo de configuración:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.test-on-borrow: true
spring.datasource.validation-query: SELECT 1 FROM DUAL
spring.datasource.log-validation-errors: true
Creo que esta es la razón por la cual no puede validar sus conexiones en el grupo, antes de usarlas.
Debe sobrescribir el método postProcessAfterInitialization para establecer las propiedades del grupo del bean TomcatJdbcDataSourceFactory de la siguiente manera:
@Component
public class PoolConfiguration implements BeanPostProcessor {
@Override
public 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;
}
}
No pude encontrar ninguna otra solución para esto. Por la forma en que esto podría ser un error del paquete de autoconfiguración Spring-Cloud-Aws .
¡Buena suerte!