2016-07-31 72 views
4

在配置DBCP2池,並且基於documentation我注意到, - 有其被描述爲一種稱爲timeBetweenEvictionRunsMillis配置:DBCP2 - 當空閒連接從池中刪除

毫秒之間睡覺的數量清除對象的運行 清除線程。如果不肯定,則不會運行空閒對象清除線程 。

其默認值爲-1

這是否意味着evictor線程永遠不會在默認配置下運行?那麼如何強制執行配置參數maxIdle - 如果池的計數大於maxIdle,則池必須驅除空閒連接。

我似乎很困惑,默認配置是這樣的,空閒連接永遠不會被驅逐。

還有另外一種配置softMiniEvictableIdleTimeMillis,它似乎在timeBetweenEvictionRunsMillis上扮演了一些角色。

在這方面的任何澄清將是巨大的幫助。

暫時我正在像下面這樣配置池 - 因爲我的目標是在池中沒有任何閒置連接太久(這是我們使用AWS RDS時所需要的,似乎有a weird issue與它在一起我們經常碰到)

BasicDataSource dataSource = new BasicDataSource(); 
    dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
    dataSource.setUrl(properties.getProperty("app.mysql.url")); 
    dataSource.setUsername(properties.getProperty("app.mysql.username")); 
    dataSource.setPassword(properties.getProperty("app.mysql.password")); 
    dataSource.setMaxIdle(20); 
    dataSource.setMaxWaitMillis(20000); //wait 10 seconds to get new connection 
    dataSource.setMaxTotal(200); 
    dataSource.setMinIdle(0); 
    dataSource.setInitialSize(10); 
    dataSource.setTestOnBorrow(true); 
    dataSource.setValidationQuery("select 1"); 
    dataSource.setValidationQueryTimeout(10); //The value is in seconds 

    dataSource.setTimeBetweenEvictionRunsMillis(600000); // 10 minutes wait to run evictor process 
    dataSource.setSoftMinEvictableIdleTimeMillis(600000); // 10 minutes wait to run evictor process 
    dataSource.setMinEvictableIdleTimeMillis(60000); // 60 seconds to wait before idle connection is evicted 
    dataSource.setMaxConnLifetimeMillis(600000); // 10 minutes is max life time 
    dataSource.setNumTestsPerEvictionRun(10); 

回答

5

是的,evictor線程默認情況下不會運行。原因是maxIdlemaxTotal的值在默認情況下是相同的,這意味着沒有連接立即關閉,也不需要排除空閒連接。所以,通過不運行無用的線程池可以節省一些資源。

但是,當您更改maxIdle並使其低於maxTotal而不啓動evictor線程時,這並不意味着您的連接將不會關閉。這意味着他們會在放出後立即關閉,不會延遲,直到他們的計數不下降到maxIdle

然後minEvictableIdleTimeMillissoftMinEvictableIdleTimeMillis前來遊玩(要小心,有文檔在一個錯字,這是...MinEvictalbe...,不...MiniEvictable...)。他們之間的區別在於前者不尊重minIdle,後者則不尊重。考慮到softMinEvictableIdleTimeMillis僅在minEvictableIdleTimeMillis過期時才被選中,這有點棘手。

我們假設我們有minEvictableIdleTimeMillis=10000softMinEvictableIdleTimeMillis=-1(默認情況下)。在這種情況下,空閒連接將保留在池中的時間不超過10秒。即使連接數不超過minIdle,它也會被關閉。如果導致連接數下降低於minIdle,則會立即創建新連接。

現在,我們假設我們有minEvictableIdleTimeMillis=10000softMinEvictableIdleTimeMillis=30000。在這種情況下,在對照minEvictableIdleTimeMillis進行檢查並檢測到超出的情況下,空閒連接將與softMinEvictableIdleTimeMillis進行額外檢查。如果空閒時間超過它,連接將被關閉。否則,它將坐在游泳池中,直到對minEvictableIdleTimeMillis進行下一次正面檢查。

最終,你必須maxTotalmaxIdle之間立即關閉連接maxIdleminIdle之間minEvictableIdleTimeMillis後關閉和連接minIdle0之間softMinEvictableIdleTimeMillis後關閉並立即重新連接。給予或採取驅逐檢查期。

使用您的配置,當池大於20時,您將立即關閉所有連接。這20個連接的活動時間爲10到20分鐘(即使空閒),因爲您有10分鐘的EvictableIdleTimeMillis加10分鐘的TimeBetweenEvictionRunsMillis

我想再提一個maxIdlemaxTotal之間差距很大的潛在問題。如果您預計maxIdle會經常被超出,最好增加它。否則,您將面臨不斷的連接開放和關閉,這將給您的數據庫帶來額外的壓力(因爲建立新的數據庫連接的操作相對較多)以及應用程序服務器網絡基礎結構(因爲關閉的連接將以TIME_WAIT狀態掛起,重新填充您的網絡端口池)。

+0

感謝您的詳細信息。那些在10-20分鐘窗口期間的空閒連接 - 它們是否會被連接池重用?我的猜測是他們會被重用。在你的第二個例子中,當你說'如果空閒時間超過它'...你的意思是它超過10000 + 30000? –

+0

謝謝,我現在閱讀你的編輯。現在很清楚 –

+0

@Wand Marker,不客氣。關於重用連接,如果我正確理解了這個問題,當然如果需要它們,池將重用它們,並且'空閒計時器'將被重置。 –