Druid鏈接池一個設置引起的血案

    今天在一臺配置很低的機器上運行批量更新的程序~~~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)

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

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爲空日誌

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

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

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

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

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

941         if (isRemoveAbandoned()) {
942                StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
943                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分鐘

    總結:

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

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

相關文章
相關標籤/搜索