请问各位在生产环境如何让 tomcat 在处理完现有的任务之后正常退出? 目前的状态是在执行 shutdown 脚本之后不会自动退出,显示有线程不能被正确停止,会导致内存泄露。

2017-11-02 16:27:06 +08:00
 qqwinds

Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/XXXXXX] registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/XXXXXX] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/XXXXXX] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak.
Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/XXXXXX] appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak.
Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/XXXXXX] appears to have started a thread named [pool-1-thread-2] but has failed to stop it. This is very likely to create a memory leak.
Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/XXXXXX] appears to have started a thread named [pool-1-thread-3] but has failed to stop it. This is very likely to create a memory leak.
Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/XXXXXX] appears to have started a thread named [pool-1-thread-4] but has failed to stop it. This is very likely to create a memory leak.
Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/XXXXXX] appears to have started a thread named [Thread-7] but has failed to stop it. This is very likely to create a memory leak.
Nov 02, 2017 3:11:39 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/XXXXXX] appears to have started a thread named [Thread-8] but has failed to stop it. This is very likely to create a memory leak.
Nov 02, 2017 3:11:39 PM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-bio-80"]
Nov 02, 2017 3:11:39 PM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-bio-8443"]
Nov 02, 2017 3:11:39 PM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-nio-443"]
Nov 02, 2017 3:11:39 PM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["ajp-bio-8009"]
Nov 02, 2017 3:11:39 PM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-bio-80"]
Nov 02, 2017 3:11:39 PM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-bio-8443"]
Nov 02, 2017 3:11:39 PM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-nio-443"]
Nov 02, 2017 3:11:39 PM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["ajp-bio-8009"]

现在已知产生这种情况的原因是有进程并未正常结束,阻止了 tomcat 的正常停止 请问各位在生产环境中一般是怎么配置的呢,如果有多台 tomcat 的话。

3765 次点击
所在节点    程序员
12 条回复
Sypher
2017-11-02 17:38:02 +08:00
以前遇到过,不是配置问题,是代码有问题啊,代码里面要关闭线程
funky
2017-11-02 17:46:43 +08:00
写个监听器实现 ServletContextListener 覆盖 contextDestroyed 方法
iyangyuan
2017-11-02 17:52:25 +08:00
检查代码才是正确选择,绝逼是有线程处于忙碌或阻塞状态,这基本上就能断定代码有 bug
aqqwiyth
2017-11-02 17:55:33 +08:00
System.exit(0)
kaneg
2017-11-02 18:02:56 +08:00
如果 shutdown 被某个线程给阻塞了, 比如加了 shutdown hook 之类的,那靠 tomcat 自己是没有可靠的办法退出了。这就需要外部强制其退出,比如用 kill -9 <pid>
qqwinds
2017-11-03 09:04:52 +08:00
@Sypher @iyangyuan 我也看出代码有问题了,问题大概在两个地方,第一个是 jdbc 没正确关闭,被强制注销。第二个应该是其他启用开始的线程的地方没有关闭。我不知道在这种情况下怎么进行调试,启用线程的地方有很多,而且基本都不是我写的。请问大佬们有什么好的找这些地方的方法不。
qqwinds
2017-11-03 09:05:03 +08:00
@aqqwiyth 这个不大合适吧。。。
qqwinds
2017-11-03 09:06:43 +08:00
@kaneg 我准备加 shutdown hook 了。。。之前一直用 kill -9 pid 的,后来发现,出现了好多问题,特别是在复杂业务的时候,业务执行完了,有时候没来得及返回结果就直接被 kill 了,客户端没收到信息,但是业务执行完了。。。比如这样
qqwinds
2017-11-03 09:17:30 +08:00
@funky 这个我没找到具体方案呢,百度未果。。。
Sypher
2017-11-03 10:25:52 +08:00
@qqwinds 除了 shutdown hook 之外,如果用框架的话,可以加一个 listener。在 contextDestroyed 里面加上你需要的代码。
类似
public class KafkaCunsumerListener implements ServletContextListener{
public void contextDestroyed(ServletContentEvent event){
//todo
}
}
最后把监听器陪在 web.xml 里面。

相当于把关闭线程绑定在 tomcat 上了
qqwinds
2017-11-03 11:42:39 +08:00
@Sypher 好的,我试一下,本来想设置守护线程,但是如果设置成守护线程还是不能合理的关闭
qqwinds
2018-01-04 09:36:34 +08:00
@iyangyuan 大佬,有个问题需要请教一下

for(;;){
code block

}
这种代码需要怎么正确关闭呢,里面是写了个获取微信 accessToken 的方法,然后采取的方案是获取完毕之后 wait 7200 秒,通过 jstack 发现这个线程在 tomcat shutdown 后仍然在 wait 中,并没有结束掉,多线程这块有点懵逼

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/402973

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX