Java tomcat app显示许多客户端连接到MySql DB

时间:2014-03-21 05:35:10

标签: java mysql tomcat

我有一个使用tomcat 7和MYSQL运行的网站。它在专用服务器上运行。我正在使用简单的连接池和简单的DAO&#39>

下面列出的课程:

我还附加了服务器上所有localhost连接的屏幕截图。我使用类似的DAO和相同的连接池在不同的服务器上运行另一个应用程序,我只在该服务器上看到4个连接。

为什么会有这么多的连接,有没有办法将它追溯到我的应用程序,看看为什么这么多产生或这是正常的?

public class ConnectionPool {

private static ConnectionPool pool = null;
private static DataSource dataSource = null;

public synchronized static ConnectionPool getInstance()
{
    if (pool == null)
    {
        pool = new ConnectionPool();
    }
    return pool;
}

private ConnectionPool()
{
    try
    {
        InitialContext ic = new InitialContext();
        dataSource = (DataSource) ic.lookup("java:comp/env/jdbc/DBNAME");
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

public Connection getConnection()
{
    try
    {
        return dataSource.getConnection();
    }
    catch (SQLException sqle)
    {
        sqle.printStackTrace();
        return null;
    }
}

public void freeConnection(Connection c)
{
    try
    {
        c.close();
    }
    catch (SQLException sqle)
    {
        sqle.printStackTrace();
    }
    catch (NullPointerException npe){
        npe.printStackTrace();
    }
}

}

DAO

    public static DefaultMetaInfo loadDefaultMetaData() {
    ConnectionPool pool = ConnectionPool.getInstance();
    Connection connection = pool.getConnection();
    PreparedStatement ps = null;
    ResultSet rs = null;

    String query = "SELECT META_TAG, TITLE_TAG FROM SITE_SETTINGS";

    try {
        ps = connection.prepareStatement(query);
        rs = ps.executeQuery();

        if (rs.next()){
            DefaultMetaInfo settings = new DefaultMetaInfo();
            settings.setMetaTag(rs.getString("META_TAG"));
            settings.setTitleTag(rs.getString("TITLE_TAG"));
            return settings;
        }
    } catch(SQLException e) {
        e.printStackTrace();
        return null;
    } finally {
        DaoUtil.closeResultSet(rs);
        DaoUtil.closePreparedStatement(ps);
        pool.freeConnection(connection);
    }
    return new DefaultMetaInfo();
}

上下文

<?xml version='1.0' encoding='utf-8'?>
    <Context>
    <Resource name="jdbc/DBNAME" 
    auth="Container" 
    type="javax.sql.DataSource"
    maxActive="1200" 
    maxIdle="30" 
    maxWait="10000" 
    testOnBorrow="true" 
    validationQuery="select 1"  
    removeAbandoned="true"      
    removeAbandonedTimeout="60"  
    logAbandoned="true"   
    username="user" 
    password="pw" 
    driverClassName="com.mysql.jdbc.Driver" 
    url="jdbc:mysql://127.0.0.1:3306/dbname?autoReconnect=true"/>
    </Context>

Client Connections

2 个答案:

答案 0 :(得分:1)

如果您注意到池中的几乎所有连接都处于SLEEP状态。

loadDefaultMetaData()方法的finally块中,您使用了以下语句为您释放连接并将其返回到已配置的连接池。

pool.freeConnection(connection);

此语句在该连接上释放您的“预订”并将其返回到池中。它不一定会关闭底层的实际数据库连接。有趣的是,freeConnection(connection)无法阻止您在connection之后再次使用free对象(如果您仍然引用它)。

由于它可以保持打开状态(通常是),因此池层可以解释未关闭的PreparedStatementResultSet作为仍然的指示。

您将能够检查或调试Connection对象以在运行时识别其状态,以确认这一点。

此问题的实际解决方案是RTM并配置连接池&amp;策略正确,如下面的参考网址所述。

Shishir

答案 1 :(得分:1)

您的配置状态为maxIdle=30,您似乎有少于30个空闲(休眠)连接。对我来说,这看起来像是预期的行为。

Shishir Kumar已经表示,当回到游泳池时,连接不一定会被关闭。原因是创建连接实际上是一项昂贵的操作,因此您通常希望将它们保持打开并重用它们 - 您还配置的validationQuery用于检查连接是否仍然有效。

恕我直言您看到的是使用连接池时的预期行为。另外,请检查您是否真的需要(并且可以处理)1200 maxActive个连接。这看起来非常高。如果你进入需要那么多开放连接的区域,你会想要有超过30个空闲。