2011-02-09 11 views
9

Estamos recibiendo una excepción CommunicationsException (de DBCP) después de un tiempo de inactividad (unas pocas horas). El mensaje de error (en la Excepción) se encuentra al final de esta pregunta, pero no veo wait_timeout definido en ninguno de los archivos de configuración. (¿Dónde deberíamos buscar? ¿En algún lugar fuera del directorio tomcat/conf?).Configuración de Tomcat utilizando DBCP

En segundo lugar, como lo sugiere la Excepción, ¿dónde se pone "Propiedad de conexión de conector/J 'autoReconnect = true'"? Aquí está la definición de recursos en el archivo conf/context.xml en Tomcat establecido:

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

En tercer lugar, ¿por qué la espera JVM hasta la llamada a executeQuery() para iniciar la excepción? Si la conexión ha excedido el tiempo de espera, el método getConnection arrojará la excepción, ¿no es así? Esta es la sección del código fuente que estoy hablando:

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

Por último, aquí están las 1ras pocas líneas de la traza de pila ...

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) 

Estas son las razones algunos de nosotros estamos pensando "olvídate dbcp, puede ser tan dependiente de las configuraciones IDE y de la magia debajo del capó que DriverManager.getConnection (...) puede ser más confiable". ¿Algún comentario sobre eso? Gracias por sus conocimientos, - MS

Respuesta

14

Desde DBCP mantiene al tanto regresaron conexiones abiertas de MySQL para las próximas solicitudes de conexión, caen víctimas al MySQL Server timeout.

DBCP tiene una serie de características que pueden ayudar (se puede utilizar a partir de Tomcat 5.5 IIRC).

validationQuery="SELECT 1" 
testOnBorrow="true" 

La validación se asegura de que una conexión es válida antes de devolverlo a una aplicación web ejecutar el método 'tomar prestado'. La bandera, por supuesto, habilita esta característica.

Si el tiempo de espera (8 horas, creo) ha transcurrido y la conexión está muerta, se prueba una nueva conexión (si ya no hay ninguna, se crea) y se proporciona a la aplicación web.

Otros enfoques posibles:

  1. uso del DBCP testWhileIdle="true" en la configuración de recursos a comprobar también las conexiones inactivas antes de que se detecte una petición eficaz.

  2. utilicen el '' ConnectionProperties se endurezcan su conexión de MySQL (por ejemplo autoReconnect/autoReconnectForPools=true)

+1

Si entiendo bien, DBCP mantiene su conexión en su grupo pero el servidor mySql la agota, así que cuando esta conexión se envía a la aplicación, es una conexión cerrada. Tiene sentido, pero ¿es eso mi correcta comprensión? Otro q: ¿Hay algún punto en el uso de validationQuery/testOnBorrow como mencionaste, así como testWhileIdle y autoRecon ... en el archivo context.xml? Van en ese archivo, ¿verdad? –

+0

1. Su comprensión es correcta. Todas las soluciones que indiqué son complementarias. Configurar uno, no impide configurar los otros. El cinturón y los tirantes son mejores ;-) Implementaría las 3 soluciones. la prueba mientras está inactivo significa menos tiempo de espera en el tiempo de "préstamo". La configuración de propiedades reducirá las desconexiones inoportunas. Sí, todos ellos se encuentran en la sección de Recursos del context.xml de su webapp (más adelante implementado por tomcat en $ CATALINA_HOME/conf/Catalina/localhost/yourwebapp.xml). –

+1

no se recomienda autoReconnect - http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html – OrangeDog

0

DBCP no está destinado para su uso en la producción, incluso los autores dicen que (ver esta presentación: http://www.infoq.com/presentations/Tuning-Tomcat-Mark-Thomas).

Sugiero echar un vistazo a C3P0: http://www.mchange.com/projects/c3p0/index.html

+1

Esto no es cierto que * *. Hay hilos sobre su comparación y la diferencia no es evidente o clara. http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0 y http://stackoverflow.com/questions/490288/is-dbcp-apache-commons-database- connection-pooling-still-relevant – Alfabravo

+0

Esa presentación habla sobre cuándo usar BIO y NIO, dependiendo de la duración de las sesiones y los requisitos de concurrencia (Tenemos pocos problemas). ¿Algún puntero sobre por qué no debería usarse en producción?¿Solo una alta frecuencia de consideraciones de conexión? Por cierto, eché un vistazo a C3P0, se ve muy interesante, podríamos probarlo si DBCP nos sigue dando problemas. Gracias por la información, - MS. –

+0

Si no recuerdo mal, hay un punto en esta presentación en que el tipo dice: "DBCP nunca fue diseñado para su uso en producción" o algo por el estilo. Sí, es una aguja en una pila de heno, pero no podía olvidar eso después de haberlo escuchado. – Spajus

Cuestiones relacionadas