2016-10-14 6 views
0

ich ein langen Lauf Problem mit meinem Jersey REST-Anwendung gehabt habe, dass der Frühling nutzt jdbcTemplate zu grundlegenden SELECT, INSERT, UPDATE zu machen, und DELETE Abfragen unserer Datenbank (DB2 wir verwenden).Frühling jdbcTemplate - Verbindung geschlossen ist

Dieses Problem tritt alle paar Tage auf, daher habe ich keine System.out des Inhalts des Fehlers (beim nächsten Mal werde ich einen Screenshot des Fehlers hinzufügen). Alle paar Tage oder so beginnen einige der Abfragen in meinen REST-Diensten aufgrund einer "Verbindung ist geschlossen". Error. Immer wenn ich diesen Fehler erhalte, starte ich einfach den Tomcat-Anwendungsserver neu und das Problem wird für einige Tage gelöst, bis es erneut auftritt.

Das Neustarten des Servers alle paar Tage wird für unsere Endbenutzer keine akzeptable Lösung sein, sobald sie damit beginnen. Wenn also irgendjemand eine Idee hat, warum dies passiert und wie ich das Problem dauerhaft lösen kann, lass es mich wissen.

Hier ist mein Frühling Datenquelle config:

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

mein application.properties hier:

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 

Mein pom.xml, wo ich die Feder jdbc und Treiber Abhängigkeiten umfassen

<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> 

Und schließlich, ein Beispiel für das Ausführen einer einfachen SELECT Abfrage mit jdbcTempla 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<>(); 
    } 
} 

EDIT: Fehler geschieht immer noch. Dieses Mal kann ich das Protokoll erfassen. Es sagt im Grunde nur "fehlgeschlagen, eine neu eingerichtete Verbindung zu validieren." Ich weiß aber nicht warum.

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: Schließlich Markierung Antwort des @ Exoddus als die richtige. Nachdem ich seine Antwort gelesen und die Spring JDBC-Dokumentation durchgesehen hatte (die mich zu der zu Grunde liegenden Tomcat-JDBC-Verbindungspool-Dokumentation führte), fing ich an, mit vielen verschiedenen Eigenschaften herumzuspielen, bis es einfach funktionierte.

Hier ist die aktuelle Konfiguration, die ich in meiner Produktionsumgebung:

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 

Wiederholen für DS2. Diese Konfiguration hat gut funktioniert, seit ich sie vor ungefähr 6 Monaten implementiert habe.

+0

Verwenden Sie einen Verbindungspool? – Ralph

+0

Ich glaube, ich mache? Ich denke, 'Spring-Boot-Starter-jdbc' verwendet Tomcat-JDBC Pooling als Standard – bscott

+0

Dank für das Tracking dieser 6 Monate später, akzeptieren Sie die Antwort und teilen Sie Ihre Gedanken! – exoddus

Antwort

2

In Ihrem Kontext würde ich versuchen, einige Parameter der DataSource Bohnen zu konfigurieren. Vielleicht haben Sie nach ein paar Tagen keine Verbindung mehr, weil einige von ihnen nie veröffentlicht oder fertiggestellt wurden (ich denke nur).

Versuchen fügte hinzu, dass Objekte zu Ihren 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 

gleiche gilt für die ds2

die richtigen Werte auf Ihrer environtment/Hardware abhängt. Werfen Sie einen Blick auf here für eine nette und präzise Erklärung über Datenquellen und Pools.

Here Sie können eine andere interessante Frage zu DataSource im Frühjahr finden, die Ihnen helfen kann.

+0

Schauen Sie sich auch den Spring-Boot-Abschnitt über Verbindungspools an: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect- to-production-database – Ralph

+0

Danke, ich werde diese für jetzt implementieren und sehen, ob dies das Problem behebt. Weil es normalerweise 1-3 Tage dauert, bis die Verbindung geschlossen ist. Fehler auftreten, ich werde warten bis Freitag nächste Woche sagen, dass der Fehler auftritt – bscott

+0

Ich aktualisierte die Werte der Eigenschaften, die Sie zur Verfügung gestellt und fügte hinzu: "ds1.datasource.validation-query =" SELECT 1 FROM SYSIBM.SYSDUMMY1 " 'und' ds1.datasource.initial-size = 10'. Auch dies ist schwer zu validieren/testen, da die Verbindung geschlossen ist. Ausgabe erschien alle paar Tage oder so. Ich werde die Bewerbung für den Rest der Woche aufrecht erhalten. Wenn die Verbindung geschlossen ist. Problem erscheint nicht nach dem Ende der Woche, ich gehe davon aus, dass diese Lösung funktioniert und dies als die richtige Antwort markieren. – bscott

Verwandte Themen