关于tomcat无法 shutdown的有关问题

关于tomcat无法 shutdown的问题

 

关于tomcat无法shutdown的问题:
 
    这个主要是由于tomcat应用服务中有非daemon线程没有关闭。而根据jvm退出规则,只要有非daemon线程存在,jvm就不会退出
 
    在我们的PerLogTask 使用Timer.schedule 周期性执行任务,里面派了出了线程,这些线程属于PerLogTask的“资源”,也只能由PerLogTask去释放 。而tomcat在shutdown时,它会回收了PerLogTask本身“资源”,却不会去回收PerLogTask申请的“资源”,造成有“资源”没有释放,jvm就不会退出。所以在tomcat回收PerLogTask“资源”时,也应该通知PerLogTask回收它自己申请的“资源”。
 
   
    解决方法:
        1、注释掉 perfLogTimer。不用这个组件,同时检查是否还有这种定时程序里分配了线程。
        2、把perfLogTimer移动到biz-context-core.xml里,由spring管理。(core-context.xml这个文件不是由spring管理的
          
         增加一个属性"destroy-method"
        <bean id="perfLogTimer" class="com.paipai.logicframework.common.perstat.PerLogTask"  init-method="init" destroy-method="clear" >
         
        因此要升级类com.paipai.logicframework.common.perstat.PerLogTask,增加了clear方法。
 
        对于用com.paipai.logicframework-3.0.1.jar的,可以从持续集成获取,已经升级。对于3.0.1版本之前的。替换掉com.paipai.logicframework.common.perstat.PerLogTask类 。见附近里。
 
 
   
 
同时说明一下:tomcat里应用服务里有线程相关的,一定要释放这些线程,按“谁申请谁释放”原则处理。






拍拍API 项目运行在Tomcat 等容器中时, 容器未能正常关闭,

比如在Tomcat 启动后, 未能通过使用shutdwon.sh 命令关闭Tomcat,

造成这个问题的主要原因是: 容器在软关闭时, 检查到容器中还有其他由容器创建的服务尚在运行,

此时容器只有等待所有的服务都结束后, 才会去真正关闭容器.

而我们的API 项目中, 有个Springbean 服务(com.paipai.logicframework.common.perstat.PerLogTask) 在容器启动时创建了定时器,

该定时器需要由Spring 容器去维护其生命周期( 启动/ 运行/ 结束),

而在我们的Spring 配置文件中只定义了该服务Bena 的启动方法, 没有去配置其结束的方法,

这就导致在Tomcat 软关闭时, 没有结束该定时器的任务, 因此Tomcat 一直处于等待关闭的状态.

 

Spring 的配置文件如下:

    core-context.xml

    <!--=====================================================================-->
    <!--
定义性能统计日志记录器-->
    <!--=====================================================================-->
    <bean id="perfLogTimer" class="com.paipai.logicframework.common.perstat.PerLogTask" init-method="init"
destroy-method="clear" >
        <description>
性能统计日志的定时记录器</description>
        <property name="delayTime">
            <description>
任务初始化延迟的时间,以秒为单位</description>
             <value>60</value>
         </property>

    </bena>

 

 

tip:

在服务容器中, 对于具有生命周期的服务( 比如定时器/ 具有阻塞方法的服务/ 异步通讯的服务),

容器都应该主动去管理好这些服务的生命周期, 便于整个容器的启动/ 关闭和运行维护.