论坛首页 Java企业应用论坛

关于tomcat7 热部署项目时的问题!

浏览 12399 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-20   最后修改:2012-12-20
以下异常是因为我设置了,根据说明我估计是因为线程不同步的情况,如果不设置backgroundProcessorDelay热部署项目不会出问题.

tomcat/conf/context.xml的backgroundProcessorDelay属性
该属性的说明:
这个值代表在context及其子容器(包括所有的wrappers)上调用backgroundProcess方法的延时,以秒为单位。如果延时值非负,子容器不会被调用,也就是说子容器使用自己的处理线程。如果该值为正,会创建一个新的线程。在等待指定的时间以后,该线程在主机及其 子容器上调用backgroundProcess方法。context利用后台处理session过期,监测类的变化用于重新载入。如果没有指定,该属性的缺省值是-1,说明context依赖其所属的Host的后台处理。

该值(backgroundProcessorDelay)是一个tomcat内部定时任务的执行时间(方法如下):
//标准的这个方法是用于tomcat定期更新session的过期时间的
public void backgroundProcess(){
   //这里是你要定期执行的代码
}



不设置backgroundProcessorDelay时的热部署情况:
2012-12-20 10:18:29 org.apache.catalina.core.StandardContext reload
信息: Reloading Context with name [/testCluster_memcached] has started
2012-12-20 10:18:30 org.apache.catalina.core.StandardContext reload
信息: Reloading Context with name [/testCluster_memcached] is completed



下面是设置了backgroundProcessorDelay时的热部署异常.
<Context backgroundProcessorDelay="10">
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
   <!-- <Manager className="net.cc.mem.MemcachedManager" sessionIdleTimeout="10" updateMemTimeout="10" poolSize="3" protocol="binary" address="192.168.0.182:11211:1,192.168.0.182:11213:1" bakAddress="192.168.0.182:11212:1,192.168.0.182:11214:1" ignoreRequestPath="(?i).*\.(png|gif|jpg|css|js|jpeg|ico)$"/>-->
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    <!-- Uncomment this to enable Comet connection tacking (provides events
         on session expiration as well as webapp lifecycle) -->
    <!--
    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    -->
</Context>



2012-12-20 10:09:17 org.apache.catalina.core.StandardContext reload
信息: Reloading Context with name [/testCluster_memcached] has started
2012-12-20 10:09:17 org.apache.catalina.core.StandardContext reload
严重: Exception stopping Context with name [/testCluster_memcached]
org.apache.catalina.LifecycleException: Failed to stop component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/testCluster_memcached]]
	at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:234)
	at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3847)
	at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:424)
	at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1214)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1400)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1389)
	at java.lang.Thread.run(Thread.java:619)
Caused by: org.apache.catalina.LifecycleException: java.lang.InterruptedException
	at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5487)
	at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:230)
	... 6 more
Caused by: java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at java.lang.Thread.join(Thread.java:1143)
	at java.lang.Thread.join(Thread.java:1196)
	at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5484)
	... 7 more
2012-12-20 10:09:17 org.apache.catalina.core.StandardContext reload
严重: Exception starting Context with name [/testCluster_memcached]
org.apache.catalina.LifecycleException: An invalid Lifecycle transition was attempted ([before_start]) for component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/testCluster_memcached]] in state [FAILED]
	at org.apache.catalina.util.LifecycleBase.invalidTransition(LifecycleBase.java:396)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:142)
	at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3854)
	at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:424)
	at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1214)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1400)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1389)
	at java.lang.Thread.run(Thread.java:619)
2012-12-20 10:09:17 org.apache.catalina.core.StandardContext reload
信息: Reloading Context with name [/testCluster_memcached] is completed
   发表时间:2012-12-24  
估计只能debug了下
0 请登录后投票
   发表时间:2012-12-24  
不建议用热部署
0 请登录后投票
   发表时间:2012-12-25  
你用的是那个版本啊 我试了一下我的tomcat 添加这个参数没有问题
0 请登录后投票
   发表时间:2012-12-25  
xiaoZ5919 写道
你用的是那个版本啊 我试了一下我的tomcat 添加这个参数没有问题

我用的是tomcat7 你试试呢!
0 请登录后投票
   发表时间:2012-12-25  
小版本 我的7.0.25 我试过了没有出现你说的问题
0 请登录后投票
   发表时间:2012-12-26  
xiaoZ5919 写道
小版本 我的7.0.25 我试过了没有出现你说的问题


不可能吧,你要重新部署项目哦!
加我QQ:497329489

我演示给你看
0 请登录后投票
   发表时间:2012-12-27  
分析堆栈上分析问题应该出在这儿
protected void threadStop() {

        if (thread == null)
            return;

        threadDone = true;
        thread.interrupt();
        try {
            thread.join();
        } catch (InterruptedException e) {
            // Ignore
        }

        thread = null;

    }

我想作者的愿意是用interrupt去中断
  while (!threadDone) {
                try {
                    Thread.sleep(backgroundProcessorDelay * 1000L);
                } catch (InterruptedException e) {
                    // Ignore
                }
然后再根据设置threadDone为true使该线程退出。
这是一个自己线程中断自己,如果执行到reload,肯定不会阻塞在thread.sleep,所以后面的thread.join会被中断
0 请登录后投票
   发表时间:2012-12-29  
xiaoZ5919 写道
分析堆栈上分析问题应该出在这儿
protected void threadStop() {

        if (thread == null)
            return;

        threadDone = true;
        thread.interrupt();
        try {
            thread.join();
        } catch (InterruptedException e) {
            // Ignore
        }

        thread = null;

    }

我想作者的愿意是用interrupt去中断
  while (!threadDone) {
                try {
                    Thread.sleep(backgroundProcessorDelay * 1000L);
                } catch (InterruptedException e) {
                    // Ignore
                }
然后再根据设置threadDone为true使该线程退出。
这是一个自己线程中断自己,如果执行到reload,肯定不会阻塞在thread.sleep,所以后面的thread.join会被中断


嗯,知道原因了,但是我无法找到 当项目热部署以后,该怎么停止这个线程,然后部署完成后又开启线程,
0 请登录后投票
   发表时间:2012-12-29  
standardcontext的reload我用的7.0.25 reload 不会重新创建一个context,这是停止原来的 再启动新的,但是因为用的同一个threadDone变量,即使设置为true已使原来的线程停止,但是这个操作是同一个线程中实现的,kill本身就创建新的。threadStart时又会设置为变量为false,使原来的也不会退出。所以没执行一次就会多加一个线程。这应该也是个bug
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics