Too few connections from Tomcat Application - java

I have a mysql database configured with a max_connections value of 150. I also have a Java 6 web application running in Tomcat 5.5 configured with the following setup:
<Resource name="jdbc/myDB"
type="javax.sql.DataSource"
driver="com.mysql.jdbc.Driver"
username="username"
password="password"
maxActive="100"
maxIdle="100"
maxWait="-1"
removeAbandoned="true"
removeAbandonedTimeout="300"
logAbandoned="true"
url="jdbc:mysql://localhost:3306/myDB?autoreconnect=true"
validationQuery="SELECT 1" />
This application is not using any 3rd party framework just basic java servlets. I have a bug in some code in the java app that is not properly releasing opened mysql connections from the pool. I am working on identifying and fixing these. But in the meantime I need to figure out why at most there is only 25 connections being allowed to mysql. After these 25 connections are used up, the application becomes unresponsive.
Can someone please help me figure out why both mysql and tomcat are configured for 100+ connections but it is only allowing 25 at a time?

Tomcat JDBC Connection Pool
What connection pool do you use?
Do you use the Tomcat JDBC Connection Pool, rather than the Apache Commons pool? It has properties to detect connection leaks or abandon connection that are open for a long time than the configured timeout.

MySQL's max_connections was set to 150 but the max_user_connections was set to 25 which was the limiting factor here. I removed this setting from my.cnf to restore it to the default value of unlimited.

Related

Connection pool in tomcat 7

Here is my current config
<Resource
name="jdbc/data"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/TABLE_NAME"
username="USER_NAME"
password="PASSWORD"
initialSize="10"
maxActive="50"
suspectTimeout="120"
minIdle="10"
maxIdle="20"
maxWait="1000"
testOnBorrow="true"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="60000"
validationQuery="SELECT 1 FROM DUAL"
validationInterval="40"
removeAbandoned="true"
removeAbandonedTimeout="100"
/>
This is in global context so multiple apps can use it.
I am little confused about parameters.need some details.
What I understand is
initalSize a number of connection created when a pool started.
maxActive maximum 50 connections can active at a time.
minIdle 10 connections remain Idle when connection is not used else are closed after maxwait
maxIdle 20 connections can be store as idle.
But When I start tomcat server I can see a 30 IDLE connections which remains forever.Why this happens? Am I missing something ? According to my understanding about connection pool there should only 10 connections should created and can stay in IDLE mode. Is there any specific changes that I have to do with mysql my.cnf
When you say...
This is in global context so multiple apps can use it.
What specifically do you mean? Is it in $CATALINA_BASE/conf/server.xml in the GlobalNamingResources block or in $CATALINA_BASE/conf/context.xml?
Defining a Resource tag in the GlobalNamingResources block of $CATALINA_BASE/conf/server.xml will cause only one resource to be created across the entire server. This can then be shared to applications deployed on your system by adding a ResourceLink tag to the Context configuration.
Defining a Resource in $CATALINA_BASE/conf/context.xml will define the resource once for each application deployed to your Tomcat instance. Thus if you have three applications deployed, you'll end up with three separate resources. This is a guess, but probably why you are seeing 30 connections to your database server.

Tomcat 7 Connection Pool Issue

I seem to have stumbled across a weird behavior with tomcat 7 and connection pooling...
In my app, I have the following 3 data sources - connecting to the same database, but different services ( and are the same across all 3)
jdbc:sybase:Tds:<db_ip_address>:<db_port>/service1
jdbc:sybase:Tds:<db_ip_address>:<db_port>/service2
jdbc:sybase:Tds:<db_ip_address>:<db_port>/service3
In my context.xml, I have the 3 data sources listed as a separate resource as usual, with all neccessary options set, including
<Resource
name="jdbc/dbDataSource1"
type="javax.sql.DataSource"
driverClassName="com.sybase.jdbc3.jdbc.SybDriver"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
maxActive="20"
initialSize="1"
minIdle="5"
maxIdle="10"
<Resource
name="jdbc/dbDataSource2"
<!-- Rest is same as above -->
<Resource
name="jdbc/dbDataSource3"
<!-- Rest is same as above -->
What I have noticed is, because the 3 data sources connect to the same database, tomcat only seems to be creating and using one connection pool and sharing between all 3. This can be seen at startup, where if I change initialSize to say 10, the first 2 data sources are created no problem - on the 3rd, I get an exception saying
java.sql.SQLException: JZ00L: Login failed.
Examine the SQLWarnings chained to this exception for the reason(s).
Am I missing something obvious here on how to set up the connection pool? I have looked at the tomcat documentation and stuff related to global connection pools, however from what I can gather this seems to be related to sharing the connections between multiple apps?
Any help is much appreciated!
Indeed seems to be too many idle connection. Try to increase the idle Connection properties or check whether you are closing all the opened connection.
Please refer to this link

attempt to reconnect jdbc pool datasource after database restarts

I have a web-app with a Java back-end that uses Tomcat jdbc-pool for database connections. This works fine.
However I am trying to foolproof it before exporting it to other locations, and recently a scenario occurred where someone restarted the SQL Server database service but did not restart the Tomcat service. This caused a SQLException: java.sql.SQLException: I/O Error: Connection reset by peer: socket write error until I restarted Tomcat, forcing the jdbc-pool datasource to reconnect.
I looked for some kind of a configuration in the Tomcat jdbc-pool docs to tell the datasource to attempt to reconnect but I couldn't find anything.
Does anyone know if there is some kind of configuration for this or should I check this condition before each request?
Not 100% sure if this is your problem but on http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency it says you can use testOnBorrow with a validationQuery.
<Resource type="javax.sql.DataSource"
...
testOnBorrow="true"
validationQuery="SELECT 1"
removeAbandoned="true"
/>
While checking for the same issue I came across this post which has the auto connect configurations for all app servers.
Below are the configuration which I used for auto connect in tomcat for reference.
<Resource auth="Container"
driverClassName="oracle.jdbc.OracleDriver"
initialSize="5"
maxActive="120"
maxIdle="5"
maxWait="5000"
name="jdbc/oracle/myds"
password="secret"
poolPreparedStatements="true"
type="javax.sql.DataSource"
url="jdbc:oracle:thin:#DBHOSTNAME:1521/ServiceName"
username="testuser"
validationQuery="select 1 from tab"
testOnBorrow="true"/>
Complete auto connect configurations for all app servers can be found here in Datasource autoreconnect in Java Application Servers.
Just to add on to Natan Cox's answer
Reference - http://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html#Common_Attributes
<Resource type="javax.sql.DataSource"
...
testOnBorrow="true"
validationQuery="SELECT 1"
removeAbandoned="true"
/>
As against Geronimo, I would still like to use validationQuery
Database validationQuery notes
hsqldb - select 1 from INFORMATION_SCHEMA.SYSTEM_USERS
Oracle - select 1 from dual
DB2 - select 1 from sysibm.sysdummy1
mysql - select 1
microsoft SQL Server - select 1
postgresql - select 1
ingres - select 1
derby - values 1
H2 - select 1
Firebird - select 1 from rdb$database
Reference - DBCP - validationQuery for different Databases

DBCP Tomcat connection pool leak

<Resource name="myConn" auth="Container"
type="javax.sql.DataSource" driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:#10.10.10.10.:1521:mydb"
username="username" password="password" maxActive="500" maxIdle="50"
maxWait="-1" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" accessToUnderlyingConnectionAllowed="true"
/>
I am trying to find out areas of the application where connections are NOT being closed. I added the removeAbandoned and logAbandoned clauses in my context file but if i check v$session on oracle it is still showing the same number of connections active even after 60 seconds. Is there something wrong in the configuration above?
I would set maxActive to smaller value like 50 and then check if the configuration is working correctly.
According to the docs the connections pool must running low to execute the check for abandoned connections:
When available db connections run low
DBCP will recover and recycle any
abandoned dB connections it finds.
I would also changed the removeAbandonedTimeout to 20 so that you won't have to wait to long to check if the detector is working fine.

Java+Tomcat, Dying database connection?

I have a tomcat instance setup but the database connection I have configured in context.xml keeps dying after periods of inactivity.
When I check the logs I get the following error:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
The last packet successfully received from the server was68051 seconds
ago. The last packet sent successfully to the server was 68051 seconds
ago, which 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.
Here is the configuration in context.xml:
<Resource name="dataSourceName"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="username"
password="********"
removeAbandoned = "true"
logAbandoned = "true"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/databasename?autoReconnect=true&useEncoding=true&characterEncoding=UTF-8" />
I am using autoReconnect=true like the error says to do, but the connection keeps dying. I have never seen this happen before.
I have also verified that all database connections are being closed properly.
Tomcat Documentation
DBCP uses the Jakarta-Commons Database Connection Pool. It relies on number of Jakarta-Commons components:
* Jakarta-Commons DBCP
* Jakarta-Commons Collections
* Jakarta-Commons Pool
This attribute may help you out.
removeAbandonedTimeout="60"
I'm using the same connection pooling stuff and I'm setting these properties to prevent the same thing it's just not configured through tomcat.
But if the first thing doesn't work try these.
testWhileIdle=true
timeBetweenEvictionRunsMillis=300000
Just to clarify what is actually causing this. MySQL by default terminates open connections after 8 hours of inactivity. However the database connection pool will retain connections for longer than that.
So by setting timeBetweenEvictionRunsMillis=300000 you are instructing the connection pool to run through connections and evict and close idle ones every 5 minutes.
The removeAbandoned option is deprecated as of DBCP 1.2 (though still present in the 1.3 branch). Here's a non-official explanation.
I do not know whether the above answer does basically the same thing, but some of our systems use the DB connection about once a week and I've seen that we provide a -Otimeout flag or something of that sort to mysql to set the connection timeout.

Categories

Resources