2016-10-14 8 views
0

Я имел длительные проблемы с моим приложением Джерси REST, который использует Spring jdbcTemplate сделать основной SELECT, INSERT, UPDATE и DELETE запросов к нашей базе данных (мы используем DB2).Spring JdbcTemplate - Соединение закрыто

Эта проблема возникает каждые несколько дней, поэтому у меня нет System.out содержимого ошибки (в следующий раз, когда это произойдет, я включу скриншот ошибки). Каждые несколько дней некоторые из запросов в моих службах REST начинают сбой из-за «Соединение закрыто». ошибка. Всякий раз, когда я получаю эту ошибку, я просто перезапускаю сервер приложений tomcat, и проблема разрешается в течение нескольких дней, пока это не начнется снова.

Перезапуск сервера каждые несколько дней не будет приемлемым решением для наших конечных пользователей, как только они начнут использовать это. Поэтому, если кто-нибудь знает, почему это происходит и как я могу постоянно решать проблему, пожалуйста, дайте мне знать.

Вот моя весна DataSource конфигурации:

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> 

И, наконец, пример того, что я выполняю простой запрос SELECT, используя jdbcTempla тэ

@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<>(); 
    } 
} 

EDIT: ошибка все еще происходит. На этот раз я смогу захватить журнал. В основном это говорит: «Не удалось проверить вновь установленное соединение». Однако я не знаю почему.

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 

EDIT # 2: ответ Наконец маркировка @ Exoddus как правильный. Прочитав его ответ и просмотрев документацию Spring JDBC, которую он предоставил (который привел меня к базовой документации для пула JDBC для Tomcat), я начал играть с множеством разных свойств, пока он не сработал.

Вот текущая конфигурация, которую я использую в своей производственной среде:

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 по умолчанию – bscott

+0

спасибо за отслеживание этого 6 месяцев спустя, примите ответ и поделитесь своими мыслями! – exoddus

ответ

2

На основании вашего контекста я попытался бы настроить некоторые параметры фасонов DataSource. Может быть, через несколько дней вы выйдете из связей, потому что некоторые из них никогда не выпускаются или не заканчиваются (я просто догадываюсь).

Попробуйте добавить, что свойства к 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 вы можете найти еще один интересный вопрос о источнике данных Spring, который может вам помочь.

+0

Также ознакомьтесь с разделом Spring Boot о пулах соединений: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-connect- to-production-database – Ralph

+0

Спасибо, я буду реализовывать их сейчас и посмотреть, устраняет ли это проблему. Потому что это обычно занимает 1-3 дня, когда «Соединение закрыто». ошибка, чтобы произойти, я подожду, пока не скажу в пятницу на следующей неделе, чтобы произошла ошибка. – bscott

+0

Я обновил значения предоставленных вами свойств и добавил еще несколько: 'ds1.datasource.validation-query =" SELECT 1 FROM SYSIBM.SYSDUMMY1 " 'и' ds1.datasource.initial-size = 10'. Опять же, это довольно сложно проверить/проверить, так как «Соединение закрыто». вопрос возникал каждые несколько дней или около того. Я продолжу приложение до конца этой недели. Если «Соединение закрыто». выпуск не появляется после окончания недели, я предполагаю, что это решение работает и помечено как правильный ответ. – bscott

Смежные вопросы