2011-04-12 88 views
1

我们有一个正常的服务器堆栈,包括BlazeDS,Tomcat和Hibernate。如何强制Apache Tomcat不重用线程池中的线程?

我们希望安排如果某些错误(特别是AssertionError)被抛出时,当前线程被认为处于未知状态,并且不会用于进一步的HTTP请求。 (部分原因是因为我们在线程本地存储中存储了一些东西,比如Hibernate事务会话。现在,我们可以捕获throwables并确保回滚事务并重新抛出,但不能保证其他代码可能留下谁知道线程本地存储中的内容)。

带默认线程池行为的Tomcat重用线程。我们试着指定我们自己的执行程序,这似乎是改变其线程池行为的最具体的方法,但它并不总是为每个请求调用Executor.execute()和一个新任务。 (很可能它会重复使用同一个HTTP连接中所有请求的相同执行上下文。)

一个选项是禁用keepalive,以便每个HTTP连接只有一个请求,但这很丑。

无论如何,我想知道。有没有办法告诉Tomcat不要重用线程,或者杀死或退出线程,以便强制Tomcat创建新线程? (从Tomcat源代码看来,Tomcat将在发送HTTP 500响应后关闭连接并放弃任务/线程,但我不知道如何让BlazeDS生成500响应;这是另一个角度I '我想知道更多关于。)

回答

4

我强烈建议简单地摆脱使用线程本地存储,或至少提出一种方法来清除线程本地存储时,请求首次进入管道(例如,在web.xml中有<filter>)。

不得不重新配置一些关于Tomcat的基本知识,以使其与您的应用程序一起工作,以指向代码味道。

+1

你可以说这个味道; OTOH也可以争辩说,这是Tomcat应该做的事情(默认情况下,未捕获的异常和错误,包括AssertionError似乎已经被丢弃在地板上,除非我错过了某些东西 - 我们已经必须编写过滤器记录所述throwables的存在)。无论如何,这不是要让Tomcat与我们的应用程序一起工作,或者我们的应用程序正在做的任何特殊事情,我认为 - 它可以工作,在异常之后继续有点过分,并且我想确保所有的基础被覆盖的。 – metamatt 2011-04-12 03:45:53

+0

是的,我们的过滤器可以在它知道的过时的线程本地状态之后清理,或者我们编写的任何代码将事物置于线程本地状态,可以使用try/catch/finally来确保清理干净。系统其他地方的其他地方也可能忘记这样做。我只是想避免这种错误。 – metamatt 2011-04-12 03:47:26

+0

还有一个想法。通过生成一个500响应来让Tomcat放弃一个线程非常简单,所以想做到这一点似乎并不是滥用Tomcat设计。真的,这是Tomcat + BlazeDS + Hibernate的组合,使得这既合意又困难。 – metamatt 2011-04-12 21:01:52