mysql - configurar - Conexiones faltantes en el grupo de conexiones tomcat jdbc
pool tomcat (3)
"¿Dónde están las conexiones que no están ocupadas?"
Parece que se han caído y, por alguna razón, su grupo de conexión no está intentando volver a conectarlos.
Agrega esto a la URL a la que te estás conectando:
autoReconnect=true
Y agregar esto como una propiedad al recurso debería hacer que las conexiones muertas se vuelvan a conectar automáticamente.
validationQuery="SELECT 1"
También esto debería permitirte ver las conexiones que se caen:
logAbandoned="true"
Hay múltiples preguntas similares en el desbordamiento de pila.
Agrupación de conexiones de Tomcat, conexiones inactivas y creación de conexiones La agrupación de conexiones de JDBC no vuelve a abrir Conexiones en tomcat
Sin embargo, también puede ser que no estés liberando las conexiones por completo, lo cual es la causa de su muerte. Prácticas de agrupación de conexiones de JDBC MySql para evitar el agotamiento de la agrupación de conexiones
Acabamos de migrar de dbcp a la agrupación de conexiones tomcat jdbc. Probamos el sistema en carga y recibimos la siguiente excepción:
java.sql.SQLException: [IA1856] Timeout: Pool empty. Unable to fetch a connection in 1 seconds, none available[size:125; busy:90; idle:0; lastwait:1000].
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:632)
at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:174)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:124)
at com.inneractive.model.mappings.BasicPersistenceEntityMapping.getConnection(BasicPersistenceEntityMapping.java:233)
at com.inneractive.model.mappings.BasicPersistenceEntityMapping.callWithConnection(BasicPersistenceEntityMapping.java:243)
at com.inneractive.model.mappings.PersistenceEntityMapping.get(PersistenceEntityMapping.java:194)
at com.inneractive.model.data.client.ClientUtils.GetClientByExamples(ClientUtils.java:353)
at com.inneractive.client.ExternalAdRingsClientStart.getClientInfoByRequestParametersOrInsert(ExternalAdRingsClientStart.java:1329)
at com.inneractive.client.ExternalAdRingsClientStart.newClientSession(ExternalAdRingsClientStart.java:245)
at com.inneractive.simpleM2M.web.SimpleM2MProtocolBean.generateCampaign(SimpleM2MProtocolBean.java:235)
at com.inneractive.simpleM2M.web.SimpleM2MProtocolBean.generateCampaign(SimpleM2MProtocolBean.java:219)
at com.inneractive.simpleM2M.web.AdsServlet.doGet(AdsServlet.java:175)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:555)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:396)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Note esto:
[size:125; busy:90; idle:0; lastwait:1000]
¿Dónde están las conexiones que no están ocupadas? El número ocupado siguió bajando después de esto, pero todavía no logramos obtener ninguna conexión.
¿Algunas ideas?
Configuración:
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" loginTimeout="10000"
maxActive="35" maxIdle="35" maxWait="1000" name="jdbc/mysql"
password="-----" testOnBorrow="true" testOnReturn="false" type="javax.sql.DataSource"
url="jdbc:mysql://localhost:3306/my_db?elideSetAutoCommits=true&useDynamicCharsetInfo=false&rewriteBatchedStatements=true&useLocalSessionState=true&useLocalTransactionState=true&alwaysSendSetIsolation=false&cacheServerConfiguration=true&noAccessToProcedureBodies=true&useUnicode=true&characterEncoding=UTF-8"
username="root" validationQuery="SELECT 1"/>
env: ubuntu y tomcat 6. db - mysql
Echando un vistazo a la fuente de ConnectionPool.java , parece que golpeas este fragmento de código en el método borrowConnection()
:
//we didn''t get a connection, lets see if we timed out
if (con == null) {
if ((System.currentTimeMillis() - now) >= maxWait) {
throw new SQLException("[" + Thread.currentThread().getName()+"] " +
"Timeout: Pool empty. Unable to fetch a connection in " + (maxWait / 1000) +
" seconds, none available["+busy.size()+" in use].");
} else {
//no timeout, lets try again
continue;
}
}
Entonces de acuerdo a esto, tu conexión es nula .
El valor de con
se recupera en la línea:
PooledConnection con = idle.poll();
si realiza un seguimiento del código, verá que el estado idle
(según su configuración, pero de forma predeterminada) es FairBlockingQueue . Puede consultar la implementación para obtener sugerencias.
En general, siempre tiene que cerrar ResultSets, Statements, Connections y las conexiones usadas deben volver a liberarse correctamente en el pool. No hacerlo correctamente puede hacer que las conexiones nunca se cierren => nunca estén disponibles nuevamente para su reutilización ("fugas" en el conjunto de conexiones).
Le sugiero que construya un registro detallado sobre el estado del grupo y lo supervise para aislar el problema.
Algunas pautas de Apache para prevenir fugas en el conjunto de conexiones de la base de datos:
removeAbandoned="true"
Las conexiones abandonadas de la base de datos son eliminadas y recicladas.
removeAbandonedTimeout="60"
establezca el número de segundos que una conexión de base de datos ha estado inactiva antes de que se considere abandonada
logAbandoned="true"
registrar un seguimiento de pila del código que abandonó los recursos de conexión de base de datos. Tenga en cuenta que "el registro de Conexiones abandonadas aumenta la sobrecarga de cada préstamo de Conexión porque se debe generar un seguimiento de pila".
Sigo pensando que aumentar ligeramente el valor maxWait
(1200, 1500, 1700 - solo experimente, no habrá diferencia en los tiempos de respuesta desde la perspectiva del usuario) borrará esos casos raros, en los que todavía tiene problemas.
parece ser un error en el grupo, la variable de size
se incrementa, luego se intenta crear una conexión, pero si la creación falla ... tenemos un valor de size
grande y no hay conexiones reales en el grupo - terrible:
//if we get here, see if we need to create one
//this is not 100% accurate since it doesn''t use a shared
//atomic variable - a connection can become idle while we are creating
//a new connection
if (size.get() < getPoolProperties().getMaxActive()) {
//atomic duplicate check
if (size.addAndGet(1) > getPoolProperties().getMaxActive()) {
//if we got here, two threads passed through the first if
size.decrementAndGet();
} else {
//create a connection, we''re below the limit
return createConnection(now, con, username, password);
}
} //end if