J'ai une application Spring-Boot sur le même hôte que la Maria DB et les deux fonctionnent bien depuis un certain temps. Mais entre 12 heures et 2 jours, il semble que l'application Spring Boot perd la connexion à la base de données (stacktrace) et ne s'en remette pas.
Lorsque je redémarre l'application de printemps, tout va bien à nouveau pendant un certain temps.
L'application n'est pas sous charge et lorsqu'elle perd la connexion, l'application fonctionne toujours mais la connexion db ne se rétablit pas. La base de données n'a pas redémarré entre-temps (durée de fonctionnement 4 semaines). Seul le service de surveillance envoie une requête ping à l'application qui envoie une requête ping à la base de données une fois par minute. (santé des bottes de printemps)
Les autres applications Java connectées à la même base de données fonctionnent correctement et ne présentent aucun problème.
Ma question est:
Pourquoi Spring ne se remet-il pas de cette erreur et essaie-t-il de se reconnecter à nouveau à la base de données? Comment puis-je configurer le ressort pour se reconnecter à la base de données?
2015-02-19 15:25:48.392 INFO 4931 [qtp92662861-19] --- o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2015-02-19 15:25:48.580 INFO 4931 [qtp92662861-19] --- o.s.jdbc.support.SQLErrorCodesFactory : SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
2015-02-19 15:25:48.616 WARN 4931 [qtp92662861-19] --- o.s.jdbc.support.SQLErrorCodesFactory : Error while extracting database product 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:296)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.Java:320)
at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.Java:214)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.Java:134)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.Java:97)
at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.Java:99)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:413)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.Java:468)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.Java:478)
at org.springframework.boot.actuate.health.DataSourceHealthIndicator.doDataSourceHealthCheck(DataSourceHealthIndicator.Java:98)
at org.springframework.boot.actuate.health.DataSourceHealthIndicator.doHealthCheck(DataSourceHealthIndicator.Java:87)
at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.Java:38)
at org.springframework.boot.actuate.endpoint.HealthEndpoint.invoke(HealthEndpoint.Java:67)
at org.springframework.boot.actuate.endpoint.HealthEndpoint.invoke(HealthEndpoint.Java:34)
at org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(HealthMvcEndpoint.Java:102)
at Sun.reflect.GeneratedMethodAccessor78.invoke(Unknown Source)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at Java.lang.reflect.Method.invoke(Method.Java:483)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.Java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.Java:749)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:961)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:852)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:790)
at org.Eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.Java:769)
at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1667)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.Java:110)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1650)
at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.Java:280)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1650)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:186)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:160)
at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1650)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.Java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1650)
at onlinevalidation.CorsFilter.doFilter(CorsFilter.Java:20)
at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1650)
at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.Java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1650)
at org.Eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.Java:583)
at org.Eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.Java:143)
at org.Eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.Java:577)
at org.Eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.Java:223)
at org.Eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.Java:1125)
at org.Eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.Java:515)
at org.Eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.Java:185)
at org.Eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.Java:1059)
at org.Eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.Java:141)
at org.Eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.Java:97)
at org.Eclipse.jetty.server.Server.handle(Server.Java:497)
at org.Eclipse.jetty.server.HttpChannel.handle(HttpChannel.Java:311)
at org.Eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.Java:248)
at org.Eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.Java:540)
at org.Eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.Java:610)
at org.Eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.Java:539)
at Java.lang.Thread.run(Thread.Java:745)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at Sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at Sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.Java:62)
at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.Java:45)
at Java.lang.reflect.Constructor.newInstance(Constructor.Java:408)
at com.mysql.jdbc.Util.handleNewInstance(Util.Java:377)
at com.mysql.jdbc.Util.getInstance(Util.Java:360)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:935)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:924)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:870)
at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.Java:1232)
at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.Java:1225)
at com.mysql.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.Java:2932)
at com.mysql.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.Java:2927)
at Sun.reflect.GeneratedMethodAccessor76.invoke(Unknown Source)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at Java.lang.reflect.Method.invoke(Method.Java:483)
at org.Apache.Tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.Java:126)
at org.Apache.Tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.Java:109)
at org.Apache.Tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.Java:80)
at com.Sun.proxy.$Proxy68.getMetaData(Unknown Source)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.Java:285)
... 66 common frames omitted
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 758,805 milliseconds ago. The last packet sent successfully to the server was 37 milliseconds ago.
at Sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at Sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.Java:62)
at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.Java:45)
at Java.lang.reflect.Constructor.newInstance(Constructor.Java:408)
at com.mysql.jdbc.Util.handleNewInstance(Util.Java:377)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.Java:1036)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.Java:3427)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.Java:3327)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.Java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.Java:2435)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.Java:2582)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.Java:2526)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.Java:2484)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.Java:1446)
at org.springframework.jdbc.core.JdbcTemplate$1QueryStatementCallback.doInStatement(JdbcTemplate.Java:452)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:402)
... 60 common frames omitted
Caused by: Java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.Java:2914)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.Java:3337)
... 69 common frames omitted
@Configuration
@ComponentScan(value = "com.demo.validation",scopedProxy = TARGET_CLASS)
@EnableAutoConfiguration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableCaching(proxyTargetClass = true)
@EnableAsync(proxyTargetClass = true)
@EnableJpaRepositories
@EnableTransactionManagement(proxyTargetClass = true)
public class Configuration {
main(...)
}
La configuration
spring.datasource.url=jdbc:mysql://localhost/validation
spring.datasource.username=validation
spring.datasource.password=****
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
Gradle.Build
dependencies {
//Boot
compile 'org.codehaus.groovy:groovy-all:2.3.7:indy'
compile 'org.springframework.boot:spring-boot-starter-actuator:1.1.8.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-security:1.1.8.RELEASE'
compile 'org.springframework:spring-aspects:4.0.7.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-aop:1.1.8.RELEASE'
compile 'org.springframework:spring-instrument:4.0.7.RELEASE'
compile('org.springframework.boot:spring-boot-starter-web:1.1.8.RELEASE'){
exclude module: 'spring-boot-starter-Tomcat'
}
//servlet container
compile 'org.Eclipse.jetty:jetty-webapp:9.2.3.v20140905'
compile 'org.Eclipse.jetty:jetty-servlets:9.2.3.v20140905'
//DB
compile 'org.springframework.boot:spring-boot-starter-data-jpa:1.1.8.RELEASE'
compile 'mysql:mysql-connector-Java:5.1.34'
//compile 'org.mariadb.jdbc:mariadb-Java-client:1.1.8'
runtime 'com.h2database:h2:1.4.182'
Par un membre senior des forums Spring , le Spring DataSource n'est pas destiné à une utilisation en production:
Les réponses ci-dessus ne sont qu'une partie de la solution. En effet, vous avez besoin d'un gestionnaire de transactions approprié ET vous avez besoin d'un pool de connexions. Le DriverManagerDataSource n'est PAS destiné à la production, il ouvre et ferme une connexion de base de données chaque fois qu'il en a besoin.
Au lieu de cela, vous pouvez utiliser C3P0 comme source de données qui gère la reconnexion et offre de bien meilleures performances. Voici un exemple rapide d'une configuration potentielle dans une configuration xml Spring:
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="#{systemProperties.dbhost}" />
<property name="user" value="#{systemProperties.dbuser}" />
<property name="password" value="#{systemProperties.dbpass}" />
<property name="maxPoolSize" value="25" />
<property name="minPoolSize" value="10" />
<property name="maxStatements" value="100" />
<property name="testConnectionOnCheckout" value="true" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="c3p0DataSource" />
</bean>
Paramètres de démarrage de Spring (3) pour l'hibernation et Oracle:
spring.datasource.test-on-borrow = true
spring.datasource.validation-query = sélectionnez 1 parmi dual
Essayez de changer l'URL de votre connexion pour:
spring.datasource.url=jdbc:mysql://localhost/validation?autoReconnect=true