【轉】Druid連接池一個設置引發的血案


https://my.oschina.net/haogrgr/blog/224010

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

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

    然后華麗麗的報異常了~~~

    具體異常是這樣的,

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為空

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

    但是這里的holder不是Spirng里面的,是Druid的

    這個holder大概是用來hou住連接池里面的連接的.

    然后為什么為空了呢? 目測是哪個鏈接壞了, 或者被意外的關閉了...

    根據異常調源碼  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分鍾

    總結:

    連接池為了防止程序從池里取得連接后忘記歸還的情況, 而提供了一些參數來設置一個租期, 使用這個可以在一定程度上防止連接泄漏

    但是如果你的業務真要跑這么久~~~~那還是注意下這個設置.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM