2016-10-14 96 views
0

我已经与我的球衣REST应用中的长时间运行的问题,利用春节jdbcTemplate进行基本SELECTINSERTUPDATEDELETE查询到我们的数据库(我们使用DB2)连接被关闭。Spring的JdbcTemplate -

这个问题每隔几天就会发生一次,所以我没有一个错误内容的System.out(下次发生错误时我会包含一个截图)。隔几天左右,由于“连接已关闭”,我的REST服务中的部分查询开始失败。错误。每当我遇到这个错误时,我只需重新启动tomcat应用程序服务器,问题就解决了几天,直到它再次发生。

每隔几天重新启动一次服务器,一旦他们开始使用它,对我们的最终用户来说将不是一个可以接受的解决方案。因此,如果任何人有任何想法,为什么发生这种情况,以及我怎么能够永久解决这个问题,请让我知道。

这里是我的春天数据源配置:

package com.my.package; 

import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.boot.context.properties.ConfigurationProperties; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Primary; 

import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; 
import javax.sql.DataSource; 

@Configuration 
public class DataSourceConfig { 

    @Bean (name = "dataSource1") 
    @Primary 
    @ConfigurationProperties(prefix = "ds1.datasource") 
    public DataSource dataSource1() { 
     return DataSourceBuilder.create().build(); 
    } 

    @Bean(name = "ds1") 
    public JdbcTemplate jdbcTemplate1(@Qualifier("dataSource1") DataSource dataSource1) { 
     return new JdbcTemplate(dataSource1); 
    } 

    @Bean (name = "dataSource2") 
    @ConfigurationProperties(prefix="ds2.datasource") 
    public DataSource dataSource2() { return DataSourceBuilder.create().build(); } 

    @Bean(name = "ds2") 
    public JdbcTemplate jdbcTemplate2(@Qualifier("dataSource2") DataSource dataSource2) { 
     return new JdbcTemplate(dataSource2); 
    } 
} 

这里是我的application.properties:

ds1.datasource.url=url1 
ds1.datasource.username=user1 
ds1.datasource.password=pass1 
ds1.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver 

ds2.datasource.url=url2 
ds2.datasource.username=user2 
ds2.datasource.password=pass2 
ds2.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver 

我的pom.xml在那里我有春天JDBC和驱动程序的依赖性

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-jdbc</artifactId> 
</dependency> 
<dependency> 
    <groupId>ibm.db2</groupId> 
    <artifactId>db2jcc4.jar</artifactId> 
    <version>4.19.26</version> 
</dependency> 

最后,我使用jdbcTempla执行一个简单的SELECT查询的例子TE

@Autowired 
@Qualifier("ds1") 
private JdbcTemplate jdbcTemplate; 

List<Something> sampleQuery(){ 
    String sqlQuery = "SELECT * FROM TABLE"; 
    try { 
     return this.jdbcTemplate.query(
       sqlQuery, 
       (rs, rowNum) -> { 

        Something something = new Something(); 
        something.setVal1(rs.getString("FIELD1").trim()); 
        something.setVal2(rs.getString("FIELD2").trim()); 

        return something; 
       }); 
    }catch (Exception ex){ 
     ex.printStackTrace(); 
     System.out.println("error..."); 
     return new ArrayList<>(); 
    } 
} 

编辑:错误仍在进行之中。这次我能够捕获日志。它基本上只是说“无法验证新建立的连接”。我不知道为什么。

org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Failed to validate a newly established connection. 
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:615) 
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680) 
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712) 
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722) 
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:772) 
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) 
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) 
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) 
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205) 
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) 
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) 
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) 
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) 
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) 
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) 
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267) 
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) 
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) 
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) 
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) 
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:261) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:115) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.sql.SQLException: Failed to validate a newly established connection. 
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:811) 
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:626) 
    at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:185) 
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:127) 
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) 
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) 
    ... 81 more 

编辑#2:最后标志着@ exoddus的答案正确的。在阅读他的回答并查看他提供的Spring JDBC文档(这使我了解了底层tomcat JDBC连接池文档)之后,我开始使用许多不同的属性,直到它正常工作。

这是当前的配置我在生产环境中使用:

ds1.datasource.url=jdbc:db2://database.domain.com:12345/DBMS 
ds1.datasource.username=admin 
ds1.datasource.password=admin 
ds1.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver 
ds1.datasource.max-active=200 
ds1.datasource.max-idle=200 
ds1.datasource.max-wait=20000 
ds1.datasource.min-idle=50 
ds1.datasource.test-while-idle=true 
ds1.datasource.test-on-borrow=true 
ds1.datasource.validation-query=SELECT 1 FROM SYSIBM.SYSDUMMY1 
ds1.datasource.time-between-eviction-runs-millis=30000 
ds1.datasource.remove-abandoned=true 
ds1.datasource.remove-abandoned-timeout=30 
ds1.datasource.abandon-when-percentage-full=50 
ds1.datasource.initial-size=50 
ds1.datasource.jdbcInterceptors=ResetAbandonedTimer 

重复的DS2。自从我大约6个月前实施这个配置以来,这种配置工作得很好。

+0

你使用连接池吗? – Ralph

+0

我相信我呢?我觉得'spring-boot-starter-jdbc'使用tomcat-jdbc pooling作为默认 – bscott

+0

,感谢6个月后的跟踪,接受回应并分享您的想法! – exoddus

回答

2

根据您的情况,我会尝试配置DataSource beans的一些参数。也许在某些日子之后,你会失去联系,因为其中一些从未被释放或完成(我只是猜测)。

尝试添加属性您application.properties:

ds1.datasource.max-active=50 
ds1.datasource.max-idle=8 
ds1.datasource.max-wait=10000 
ds1.datasource.min-idle=4 
ds1.datasource.test-on-borrow=true 

同为ds2

的正确值取决于你environtment /硬件。请看here,以获得关于数据源和池的更好和简明的解释。

Here你可以在春天找到关于DataSource的另一个有趣的问题,它可以帮助你。

+0

另请参阅有关连接池的Spring Boot部分:http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-生产数据库 – Ralph

+0

谢谢,我现在将执行这些,看看这是否解决了这个问题。因为“连接已关闭”通常需要1-3天。错误发生,我会等到下周五说错误发生 – bscott

+0

我更新了您提供的属性的值并添加了更多内容:'ds1.datasource.validation-query =“SELECT 1 FROM SYSIBM.SYSDUMMY1” '和'ds1.datasource.initial-size = 10'。同样,自“连接已关闭”以来,这是很难验证/测试的。问题每隔几天出现一次。我将在本周的其余时间继续使用该应用程序。如果“连接已关闭”。问题不会在本周结束后出现,我会假设此解决方案起作用并将其标记为正确答案。 – bscott

相关问题