2011-02-09 18 views
9

Otteniamo una CommunicationsException (da DBCP) dopo un periodo di inattività (alcune ore). Il messaggio di errore (nell'eccezione) si trova alla fine di questa domanda, ma non vedo wait_timeout definito in nessuno dei file di configurazione. (Dove dovremmo guardare? Da qualche parte fuori dalla directory tomcat/conf?).Configurazione Tomcat tramite DBCP

In secondo luogo, come suggerito dall'eccezione, dove si inserisce la "proprietà Connection/J connection" autoReconnect = true ""? Ecco la definizione di risorse nel file conf/context.xml in Tomcat impostare:

<Resource name="jdbc/TomcatResourceName" auth="Container" type="javax.sql.DataSource" 
      maxActive="100" maxIdle="30" maxWait="10000" 
      removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" 
      username="xxxx" password="yyyy" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://127.0.0.1:3306/dbname?autoReconnect=true"/> 

In terzo luogo, perché la JVM aspettare fino alla chiamata a executeQuery() per generare l'eccezione? Se la connessione è scaduta, il metodo getConnection dovrebbe lanciare l'eccezione, vero? Questa è la sezione del codice sorgente di cui sto parlando:

 try { 
       conn = getConnection (true); 
       stmt = conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE, 
               ResultSet.CONCUR_READ_ONLY); 
       rset = stmt.executeQuery (bQuery); 
       while (rset.next()) { 
        .... 

Infine, ecco il 1 ° poche righe della traccia dello stack ...

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 84,160,724 milliseconds ago. The last packet sent successfully to the server was 84,160,848 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:532) 
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074) 
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3291) 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1938) 
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2107) 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2642) 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2571) 
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1451) 
at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208) 

Queste sono le ragioni per alcuni di noi sono pensando "dimentica dbcp, potrebbe essere così dipendente dalle configurazioni IDE e dalla magia nascosta che DriverManager.getConnection (...) potrebbe essere più affidabile". Qualche commento su questo? Grazie per i vostri approfondimenti, - MS

risposta

14

Dal DBCP continua a restituite le connessioni MySQL open per le richieste di connessione in arrivo, cadono vittime al MySQL Server timeout.

DBCP ha un numero di funzionalità che possono essere d'aiuto (può essere utilizzato a partire da Tomcat 5.5 IIRC).

validationQuery="SELECT 1" 
testOnBorrow="true" 

La convalida fa in modo che una connessione è valida prima di tornare a una webapp esecuzione del metodo di 'prendere in prestito'. La bandiera ovviamente abilita questa funzionalità.

Se il timeout (8 ore credo) è scaduto e la connessione è morta, viene verificata una nuova connessione (se non ce ne sono più, viene creata) e fornita alla webapp.

Altri approcci possibili:

  1. uso del DBCP testWhileIdle="true" nelle impostazioni di risorse per controllare anche le connessioni inattive prima che venga rilevata una richiesta efficace.

  2. utilizzare il 'ConnectionProperties' per indurire la tua connessione MySQL (ad esempio autoReconnect/autoReconnectForPools=true)

+1

Se ho capito bene, DBCP mantiene la sua connessione nel suo pool ma il server mySql lo ritarda, quindi quando questa connessione viene inviato all'app, è una connessione chiusa. Ha senso, ma è la mia comprensione corretta? Un altro q: C'è qualche punto nell'usare validationQuery/testOnBorrow come hai menzionato così come testWhileIdle e autoRecon ... nel file context.xml? Vanno in quel file, giusto? –

+0

1. La tua comprensione è corretta. Tutte le soluzioni che ho indicato sono complementari. Impostarne uno, non impedisce di impostare gli altri. Cintura e bretelle sono migliori ;-) Implementerei tutte e 3 le soluzioni. test mentre inattivo significa meno tempo di attesa in "prestito". Le impostazioni delle proprietà ridurranno le disconnessioni inopportune. Sì, tutti vanno nella parte Risorse del contesto.xml del tuo webapp (successivamente implementato da tomcat in $ CATALINA_HOME/conf/Catalina/localhost/yourwebapp.xml). –

+1

autoReconnect non è raccomandato - http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html – OrangeDog

0

DBCP non è pensato per l'uso in produzione, anche gli autori dicono che (vedere questa presentazione: http://www.infoq.com/presentations/Tuning-Tomcat-Mark-Thomas).

vi suggerisco di dare un'occhiata a C3P0: http://www.mchange.com/projects/c3p0/index.html

+1

Questo non è * vero *. Ci sono discussioni sul tuo confronto e la differenza non è evidente o chiara. http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0 e http://stackoverflow.com/questions/490288/is-dbcp-apache-commons-database- connection-pooling-still-relevant – Alfabravo

+0

Questa presentazione parla di quando utilizzare BIO e NIO, a seconda delle lunghezze della sessione e dei requisiti di concorrenza (Siamo in basso su entrambi i problemi). Qualche puntatore sul perché non dovrebbe essere usato in produzione?Solo alta frequenza di considerazioni sulla connessione? A proposito, ho dato un'occhiata al C3P0, sembra molto interessante, potremmo provarlo se DBCP continua a darci problemi. Grazie per le informazioni, - MS. –

+0

Se ricordo correttamente c'è un punto in questa presentazione quando il ragazzo dice "DBCP non è mai stato pensato per l'uso in produzione" o qualcosa del genere. Sì, è un ago in una pila di fieno, ma non posso dimenticarlo dopo averlo sentito. – Spajus

Problemi correlati