Druid鏈接池一個設置引起的血案【abandon connection, open stackTrace】

今天在一臺配置很低的機器上運行批量更新的程序~~~java

    大概跑了三十分鐘~~~這配置~~~這程序~~~spring

    而後華麗麗的報異常了~~~sql

    具體異常是這樣的,ui

DEBUG: (BaseJdbcLogger.java:132)    ooo Using Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@4d4e22e1]

[2014-07-17 15:19:35]5363945354 [Druid-ConnectionPool-Destory-1422598563] com.alibaba.druid.pool.DruidDataSource:1132 

WARN : (DruidDataSource.java:1132)   get/close not same thread

 

ERROR: (DruidDataSource.java:1815)   abandon connection, open stackTrace

        at java.lang.Thread.getStackTrace(Thread.java:1588)

    at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:942)

    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4534)

    at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:661)

    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4530)

    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:880)

    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:872)

    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:97)

這個是最初的異常, 後面還有一大批異常,日誌

Caused by: java.sql.SQLException: connection holder is null

    at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1085)

    at com.alibaba.druid.pool.DruidPooledConnection.getMetaData(DruidPooledConnection.java:825)

    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:285)

    ... 70 more

說什麼holder爲空code

    第一眼看到holder就像到Spring的源碼, 裏面處處是holder(笑)rem

    可是這裏的holder不是Spirng裏面的,是Druid的get

    這個holder大概是用來hou住鏈接池裏面的鏈接的.源碼

    而後爲何爲空了呢? 目測是哪一個連接壞了, 或者被意外的關閉了...it

    根據異常調源碼  at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:942)

if (isRemoveAbandoned()) {

              StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

              poolalbeConnection.setConnectStackTrace(stackTrace);

              poolalbeConnection.setConnectedTimeNano();

              poolalbeConnection.setTraceEnable(true);

 

              synchronized (activeConnections) {

                  activeConnections.put(poolalbeConnection, PRESENT);

              }

         }

 看不出啥來. 只能將日誌繼續看看, 仍是看不出啥來

    而後看了上面代碼幾遍後, 老以爲 isRemoveAbandoned() 這個方法有鬼.

    查看調用處,:

 

恩, 這個DestroyConnectionThread很是可疑, 跳

if (isRemoveAbandoned()) {

   removeAbandoned();

}
public int removeAbandoned() {

        int removeCount = 0;

 

        long currrentNanos = System.nanoTime();

 

        List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();

 

        synchronized (activeConnections) {

            Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();

 

            for (; iter.hasNext();) {

                DruidPooledConnection pooledConnection = iter.next();

 

                if (pooledConnection.isRunning()) {

                    continue;

                }

 

                long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);

 

                if (timeMillis >= removeAbandonedTimeoutMillis) {

                    iter.remove();

                    pooledConnection.setTraceEnable(false);

                    abandonedList.add(pooledConnection);

                }

            }

        } ....略

    }

擦, 這裏不對頭,   timeMillis >= removeAbandonedTimeoutMillis  timeMillis 這個是getConnection()被調用時的時間

    意思就是一個鏈接被get後, 超過了 removeAbandonedTimeoutMillis這麼久我就弄死你.

    而後繼續找removeAbandonedTimeoutMillis 這玩意在哪裏設置的   ,最後發現是在

<property name="removeAbandoned" value="true" />

<property name="removeAbandonedTimeout" value="1800" />

    初始化配置的這裏設置的,  這兩個參數的大概意思就是, 

    經過datasource.getConnontion() 取得的鏈接必須在removeAbandonedTimeout這麼多秒內調用close(),要不我就弄死你.(就是conn不能超過指定的租期)

    而後調成2個小時~~~

    而後程序成功跑完~~~華麗麗的等了50分鐘

    總結:

    鏈接池爲了防止程序從池裏取得鏈接後忘記歸還的狀況, 而提供了一些參數來設置一個租期, 使用這個能夠在必定程度上防止鏈接泄漏

    可是若是你的業務真要跑這麼久~~~~那仍是注意下這個設置.

相關文章
相關標籤/搜索