简体   繁体   English

Tomcat连接池中的基本问题

[英]Fundamental issue in connection pooling of Tomcat

I am using Tomcat 7 connection pooling (as a Tomcat resource in server.xml and context.xml) in a web application and it works. 我在Web应用程序中使用Tomcat 7连接池(作为server.xml和context.xml中的T​​omcat资源)并且它可以工作。
My question is: Is it possible to "tell"/"force" tomcat to dispose the connection pool after it is created? 我的问题是:是否有可能“告诉”/“强制”tomcat在创建后配置连接池?

The reason I ask is the following: 我问的原因如下:
I am using H2 and run into some "racing" issue on shutdown. 我正在使用H2并在关机时遇到一些“赛车”问题。
H2 remains open as long as there is a connection open but Tomcat does not dispose the connection pool and so connections remain open. 只要连接打开, H2保持打开状态,但Tomcat不会释放连接池,因此连接仍保持打开状态。 And as a result I have various issues on shutdown. 结果我在关机时遇到了各种各样的问题。

I found that I could issue an SQL SHUTDOWN command to close H2 but I want to explore all the alternatives for my case. 我发现我可以发出一个SQL SHUTDOWN命令来关闭H2,但我想探索我案例的所有替代方案。

So is it possible to "tell"/"force" tomcat to dispose the connection pool (at least on shutdown)? 那么是否可以“告诉”/“强制”tomcat配置连接池(至少在关机时)?

I think you can try to put debug log on and check whether its issue with connection not released by application or something else like datasource configuration parameter in server.xml. 我认为您可以尝试将调试日志放入其中并检查其连接问题是否未由应用程序发布,或者是否与server.xml中的数据源配置参数等相关。

mostly it should be the case where application is not releasing connection. 大多数应该是应用程序没有释放连接的情况。

How about writing a custom ServletContextListener and then having it shut down the pool when the context is destroyed. 如何编写自定义ServletContextListener,然后在上下文被销毁时关闭池。 Here's an article about ServletContextListener being used to create shutdown hooks: 这是一篇关于用于创建关闭钩子的ServletContextListener的文章:

shutdown hook for java web application 用于java Web应用程序的shutdown hook

The API for context listeners seems pretty straightforward: 上下文侦听器的API看起来非常简单:

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

please see my answer in : Context specific JNDI parameters problem in tomcat 6 . 请参阅我的答案: tomcat 6中的特定上下文的JNDI参数问题 There's a lot of stuff you can do with jndi resource. 你可以用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"/>

As described in documentation http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Resource_Definitions it possible to set closeMethod of container datasource. 如文档http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Resource_Definitions中所述 ,可以设置容器数据源的closeMethod。 I'm not sure about 'disposing' connection pool, but i think it worth a try. 我不确定'处理'连接池,但我认为值得一试。

Name of the zero-argument method to call on a singleton resource when it is no longer required. 不再需要时,在单例资源上调用的零参数方法的名称。 This is intended to speed up clean-up of resources that would otherwise happen as part of garbage collection. 这旨在加速清理资源,否则这些资源将作为垃圾收集的一部分发生。 This attribute is ignored if the singleton attribute is false. 如果singleton属性为false,则忽略此属性。 If not specificed, no default is defined and no close method will be called. 如果未指定,则不定义默认值,也不会调用close方法。

Also you can deploy DataSource programmatically and start/stop it in ServletContextListener , example for dbcp (sorry, it from my unit-tests, but easy to rewrite): 你也可以编程方式部署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();
}

Maybe I don't understand the question. 也许我不明白这个问题。 To be more clear, if you shutdown Tomcat (and hence it's JVM), then neither Tomcat nor it's connection pools, nor any of it's daemon threads would still be alive ... and thus no memory references would be left in tack. 更清楚的是,如果你关闭Tomcat(因此它是JVM),那么Tomcat和它的连接池,以及它的任何守护程序线程都不会活着......因此没有内存引用会留下来。

How exactly have you come to the conclusion that a Tomcat resource has a reference to a connection pool, after Tomcat is shutdown? 在Tomcat关闭之后,您究竟如何得出Tomcat资源对连接池的引用? You wouldn't be able to see that in a profiler, and frankly, it doesn't quite make sense. 你无法在剖析器中看到它,坦率地说,它没有多大意义。 For example, is it possible that the OS keeps connections open for a short period of time before destroying them? 例如,操作系统是否有可能在销毁之前将连接保持打开一小段时间? Have you tried the same tests using the same OS, but instead with a different container, something like Jetty? 您是否尝试使用相同的操作系统进行相同的测试,而是使用不同的容器,比如Jetty? Are you using keep-alives, or some form of persistent connections? 您使用的是keep-alives还是某种形式的持久连接?

If you want to get down-and-dirty with Tomcat's management of a resource exposed through JNDI, you can make your own DataSource implementation that delegates to the H2 DataSource. 如果您希望通过Tomcat对通过JNDI公开的资源进行管理而变得肮脏,您可以创建自己的代理到H2 DataSource的DataSource实现。 You can do this my using the factory-method attribute within your server.xml (or context.xml) 您可以使用server.xml(或context.xml)中的factory-method属性执行此操作

Here's a working example on github : https://github.com/tvollmer/connection-factory 这是github上的一个工作示例: https//github.com/tvollmer/connection-factory

Beyond that, it would help if you could further clarify what you mean by "various issues on shutdown". 除此之外,如果您可以通过“关闭时的各种问题”进一步澄清您的意思,将会有所帮助。 Those details matter, and it's not clear to me how you've logically gone from "various issues" to saying that Tomcat "does not dispose the connection pool". 这些细节很重要,我不清楚你是如何逻辑地从“各种问题”走向说Tomcat“没有处理连接池”。 You could be dealing with 2 completely separate issues here, and you may want to check out antiResourceLocking and antiJARLocking settings for Tomcat on Windows. 你可能在这里处理2个完全独立的问题,你可能想在Windows上检查Tomcat的antiResourceLockingantiJARLocking设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM