Maria DBと同じホストにスプリングブートアプリケーションがあり、両方ともしばらくの間正常に動作しています。ただし、12時間から2日の間は、スプリングブートアプリケーションがデータベースへの接続(スタックトレース)を失い、そこから回復しないようです。
Springアプリケーションを再起動すると、しばらくの間すべてが正常になります。
アプリケーションには負荷がかかっておらず、接続を失ってもアプリケーションは動作していますが、db接続は回復しません。 DBはその間(稼働時間4週間)再起動しませんでした。監視サービスのみが、1分に1回DBにpingを実行するアプリケーションにpingを実行します。 (春のブーツの健康)
他のJava同じDBに接続されているアプリケーションは正常に実行されており、問題はありません。
私の質問は:
なぜspringはそのエラーから回復せず、DBへの再接続を再試行しますか? DBに再接続するようにスプリングを設定するにはどうすればよいですか?
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(...)
}
構成
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'
Spring forums の上級メンバーによると、Spring DataSourceは本番用ではありません:
上記の回答は、ソリューションの一部にすぎません。実際、適切なトランザクション管理が必要であり、接続プールが必要です。 DriverManagerDataSourceは本番用ではありません。必要なたびにデータベース接続を開いたり閉じたりします。
代わりに、再接続を処理し、パフォーマンスがはるかに優れたデータソースとしてC3P0を使用できます。次に、Spring xml構成の潜在的な構成の簡単な例を示します。
<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>
休止状態およびOracleのSpring(3)ブート設定:
spring.datasource.test-on-borrow = true
spring.datasource.validation-query =デュアルから1を選択
接続URLを次のように変更してみてください。
spring.datasource.url=jdbc:mysql://localhost/validation?autoReconnect=true