Repository navigation
Tomcat 不能 graceful shutdown #535
Copy link
Copy link
Description
我的配置是 tomcat + spring boot mvc,从spring boot 的例子工程中修改出来的,sdk 的版本 2.9.6。部署到tomcat下运行,不能正常的shutdown,有很多线程不能shutdown,例如:
12-Apr-2018 20:24:51.951 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [pool-2-thread-9] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)
还有这类的:
12-Apr-2018 20:24:52.004 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@2926f399]) and a value of type [com.github.binarywang.wxpay.bean.WxPayApiData] (value [
【请求地址】:https://api.mch.weixin.qq.com/pay/unifiedorder
【请求数据】:<xml>
<appid>wxxxxxxx</appid>
<mch_id>1xxx</mch_id>
<nonce_str>1523530799119</nonce_str>
<sign>3D1?????????????</sign>
<body>abcddd</body>
<out_trade_no>tx-341</out_trade_no>
<total_fee>1</total_fee>
<spbill_create_ip>172.31.233.29</spbill_create_ip>
<time_start>20180412185959</time_start>
<time_expire>20180412205959</time_expire>
<notify_url>http://mp.x.moxxbi.com/pay/notify</notify_url>
<trade_type>JSAPI</trade_type>
<openid>oEKyxCRT93OmoI</openid>
</xml>
【响应数据】:<xml><return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx????da0???]]></appid>
<mch_id><![CDATA[14966786487324-002]]></mch_id>
<nonce_str><![CDATA[EyuXgXeSJyDAeM4W]]></nonce_str>
<sign><![CDATA[F1C2CF6??????618B4D56EE74495A4686]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx12x883721bd45d2797498456]]></prepay_id>
<trade_type><![CDATA[JSAPI]]></trade_type>
</xml>]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
我没看到在哪里设置graceful shutdown相关的配置,
请求帮助
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
binarywang commentedon Apr 12, 2018
你这两种错误都属于网上常见警告或错误,并不影响使用,不过既然你觉得不爽,就可以在网上搜索对应相关错误信息,会找到很多种不同的分析和解决办法
gtyang commentedon Apr 13, 2018
这个问题的影响是不能正常的 shutdown tomcat,还要手工的 kill 进程,这个比较影响运维。
通常来讲这个问题是线程池没有shutdown,但是我不知道是那里的线程池,能找到这个线程池,我说可以在shutdown的钩子里去关闭它。
binarywang commentedon Apr 13, 2018
那我明白你的意思了,第一个我估计应该是那个后台定期关闭空闲http请求的线程,第二个的话是使用的ThreadLocal的那个类,类名上面也列出来了,你可以先研究下怎么处理,如有可行办法,可以提供下,供其他人参考,或者如果是sdk需要配合修改的,麻烦提供一个PR,谢谢了
gtyang commentedon Apr 13, 2018
初步判断,是 WxMpMessageRouter 启动了一个线程池,但是没有shutdown。这个类没有暴露出这个线程池,所以没有办法处理这个池。
fix issue binarywang#535 Tomcat 不能 graceful shutdown,增加线程池shutdown相关的操作
#535 修复Tomcat 不能正常关闭的问题,增加线程池shutdown相关的操作
binarywang commentedon Apr 16, 2018
3.0.2.BETA版本已加入相关支持
gtyang commentedon Apr 17, 2018
实证问题解决了 :)
合并 Develop,发布3.1.0正式版 (#640)
nadirvishun commentedon Apr 10, 2022
同样遇到此问题,但是目前此pr只是能解决“微信公众号”的问题,企业微信的还是没有shutdown方法关闭,而且企业微信与公众号不同的是多个应用会存在多个
WxCpService和多个WxCpMessageRouter,因为他不是和企业微信一样是用単例实现用switchover方式切换的,所以仅仅是增加shutdown方法也不好调用。而且shutdown方法最好增加awaitTermination()方法来保证超时关闭。@binarywang ,麻烦看下能否修改企业微信sdk的调用方式和微信公众号一致(或者能实现关闭线程池也行)?并增加
shutdown方法?binarywang commentedon Apr 10, 2022
欢迎直接提供PR
nadirvishun commentedon Apr 11, 2022
企业微信如果要改成和公众号类似的单例的形式我这边要提交pr的话有几个问题:
agentId并不一定是唯一的,如果恰好要集成多个企业的微信的话,可能会有冲突,所以是不是在WxCpDefaultConfigImpl中再增加一个成员变量cpId比较好,如果是单个企业,则可以用agentId赋值给cpId,多个企业可以用corpId + agentId赋值给cpId,或者是自定义能保证唯一就行。上方的pr仅仅是提交了增加线程池关闭的方法,如果有多个实例,那就遍历多个来结束线程池,暂时是能满足要求的,但是其它的都是单例的形式运行,就企业微信要实例化好几个,从行为上来说不是很统一。