簡體   English   中英

Tomcat連接池中的基本問題

[英]Fundamental issue in connection pooling of Tomcat

我在Web應用程序中使用Tomcat 7連接池(作為server.xml和context.xml中的T​​omcat資源)並且它可以工作。
我的問題是:是否有可能“告訴”/“強制”tomcat在創建后配置連接池?

我問的原因如下:
我正在使用H2並在關機時遇到一些“賽車”問題。
只要連接打開, H2保持打開狀態,但Tomcat不會釋放連接池,因此連接仍保持打開狀態。 結果我在關機時遇到了各種各樣的問題。

我發現我可以發出一個SQL SHUTDOWN命令來關閉H2,但我想探索我案例的所有替代方案。

那么是否可以“告訴”/“強制”tomcat配置連接池(至少在關機時)?

我認為您可以嘗試將調試日志放入其中並檢查其連接問題是否未由應用程序發布,或者是否與server.xml中的數據源配置參數等相關。

大多數應該是應用程序沒有釋放連接的情況。

如何編寫自定義ServletContextListener,然后在上下文被銷毀時關閉池。 這是一篇關於用於創建關閉鈎子的ServletContextListener的文章:

用於java Web應用程序的shutdown hook

上下文偵聽器的API看起來非常簡單:

http://docs.oracle.com/javaee/5/api/javax/servlet/ServletContextListener.html

請參閱我的答案: tomcat 6中的特定上下文的JNDI參數問題 你可以用jndi資源做很多事情。

<Resource name="jdbc/NAME" auth="Container" type="javax.sql.DataSource"
               maxActive="100" minIdle="10" maxWait="10000" removeAbandoned="true"
               removeAbandonedTimeout="60" logAbandoned="true"
               testWhileIdle="true" testOnBorrow="true" testOnReturn="false"
               timeBetweenEvictionRunsMillis="5000"
               validationQuery="SELECT 1" initialSize="10"
               username="usrname" password="password"   
               driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/databb?autoReconnect=true"/>

如文檔http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Resource_Definitions中所述 ,可以設置容器數據源的closeMethod。 我不確定'處理'連接池,但我認為值得一試。

不再需要時,在單例資源上調用的零參數方法的名稱。 這旨在加速清理資源,否則這些資源將作為垃圾收集的一部分發生。 如果singleton屬性為false,則忽略此屬性。 如果未指定,則不定義默認值,也不會調用close方法。

你也可以編程方式部署DataSource並在ServletContextListener啟動/停止它,例如dbcp (對不起,它來自我的單元測試,但很容易重寫):

import org.apache.commons.dbcp.BasicDataSource;

static BasicDataSource bds = new BasicDataSource();

@BeforeClass
public void setUp() throws Exception {
    bds.setDefaultAutoCommit(false);
    bds.setDriverClassName("org.h2.Driver");
    bds.setInitialSize(0);
    bds.setMaxActive(2);
    bds.setMaxWait(10000);
    bds.setPassword(null);
    bds.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
    bds.setUsername("sa");
    bds.setValidationQuery("select 1 as test");
}

@AfterClass
public void tearDown() throws Exception {
    bds.close();
}

也許我不明白這個問題。 更清楚的是,如果你關閉Tomcat(因此它是JVM),那么Tomcat和它的連接池,以及它的任何守護程序線程都不會活着......因此沒有內存引用會留下來。

在Tomcat關閉之后,您究竟如何得出Tomcat資源對連接池的引用? 你無法在剖析器中看到它,坦率地說,它沒有多大意義。 例如,操作系統是否有可能在銷毀之前將連接保持打開一小段時間? 您是否嘗試使用相同的操作系統進行相同的測試,而是使用不同的容器,比如Jetty? 您使用的是keep-alives還是某種形式的持久連接?

如果您希望通過Tomcat對通過JNDI公開的資源進行管理而變得骯臟,您可以創建自己的代理到H2 DataSource的DataSource實現。 您可以使用server.xml(或context.xml)中的factory-method屬性執行此操作

這是github上的一個工作示例: https//github.com/tvollmer/connection-factory

除此之外,如果您可以通過“關閉時的各種問題”進一步澄清您的意思,將會有所幫助。 這些細節很重要,我不清楚你是如何邏輯地從“各種問題”走向說Tomcat“沒有處理連接池”。 你可能在這里處理2個完全獨立的問題,你可能想在Windows上檢查Tomcat的antiResourceLockingantiJARLocking設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM