`
gogole_09
  • 浏览: 205572 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Tomcat生命周期管理

阅读更多

在之前的 Tomcat 整体架构中可以看到 Tomcat 包含多个很多个组件 , 今天我们来看看, Tomcat 是如何管理这些组件的生命周期的。
我们知道,组件与组件之间,必须建立起相互的关系,才能做到同时启动与停止。 Tomcat 内部,使用一个观察者模式来组织这些组件之间的关系。
我们来看看, Tomcat 启动时,它会做哪些处理……
日志:

……

2010-6-19 15:41:18 org.apache.catalina.core.StandardService start
信息 : Starting service Catalina
2010-6-19 15:41:18 org.apache.catalina.core.StandardEngine start
信息 : Starting Servlet Engine: Apache Tomcat/6.0.18
…
2010-6-19 15:41:19 org.apache.coyote.http11.Http11Protocol start
信息 : Starting Coyote HTTP/1.1 on http-8080
2010-6-19 15:41:19 org.apache.jk.common.ChannelSocket init
信息 : JK: ajp13 listening on /0.0.0.0:8009
2010-6-19 15:41:19 org.apache.jk.server.JkMain start
信息 : Jk running ID=0 time=0/182 config=null
2010-6-19 15:41:19 org.apache.catalina.startup.Catalina start
信息 : Server startup in 1706 ms
 



我们看到,它的启动顺序:

StandardService --> StandardEngine-->Http11Protocol-->JkMain-->Catalina
 


OK, 我们来看看在 Tomcat 内部的,他是如何做的
首先, Tomcat内部的生命周期的相关定义都在接口 Lifecycle 中,

 

package org.apache.catalina;


public interface Lifecycle {

    public static final String INIT_EVENT = "init";

    public static final String START_EVENT = "start";

    public static final String BEFORE_START_EVENT = "before_start";

    public static final String AFTER_START_EVENT = "after_start";
    public static final String STOP_EVENT = "stop";
    public static final String BEFORE_STOP_EVENT = "before_stop";
    public static final String AFTER_STOP_EVENT = "after_stop";
    public static final String DESTROY_EVENT = "destroy";
    public static final String PERIODIC_EVENT = "periodic";
    public void addLifecycleListener(LifecycleListener listener);
    public LifecycleListener[] findLifecycleListeners();
    public void removeLifecycleListener(LifecycleListener listener);
    public void start() throws LifecycleException;
    public void stop() throws LifecycleException;
}

 

另外生命周期的相关事件,定义在 LifecycleEvent 类中

 

 

 

package org.apache.catalina;



import java.util.EventObject;


public final class LifecycleEvent

    extends EventObject {
    // ----------------------------------------------------------- Constructors
    public LifecycleEvent(Lifecycle lifecycle, String type) {
        this(lifecycle, type, null);
    }

    public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
        super(lifecycle);
        this.lifecycle = lifecycle;
        this.type = type;
        this.data = data;
    }

    private Object data = null;

    private Lifecycle lifecycle = null;

    private String type = null;

    public Object getData() {
        return (this.data);
    }

    public Lifecycle getLifecycle() {
        return (this.lifecycle);
    }

    public String getType() {
        return (this.type);
    }

}

 

 

关于事件的监听,在接口LifecycleListener 中有定义

 

 

package org.apache.catalina;

public interface LifecycleListener {
    public void lifecycleEvent(LifecycleEvent event);
}

 

 另外,这里还需要介绍一个特别的类:LifecycleSupport, 用于触发生命周期的相关事件.

 

package org.apache.catalina.util;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;

public final class LifecycleSupport {
    public LifecycleSupport(Lifecycle lifecycle) {
        super();
        this.lifecycle = lifecycle;
    }

    private Lifecycle lifecycle = null;
    private LifecycleListener listeners[] = new LifecycleListener[0];
    private final Object listenersLock = new Object(); // Lock object for changes to listeners
    public void addLifecycleListener(LifecycleListener listener) {
      synchronized (listenersLock) {
          LifecycleListener results[] =
            new LifecycleListener[listeners.length + 1];
          for (int i = 0; i < listeners.length; i++)
              results[i] = listeners[i];
          results[listeners.length] = listener;
          listeners = results;
      }
    }

    public LifecycleListener[] findLifecycleListeners() {
        return listeners;
    }

    public void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        LifecycleListener interested[] = listeners;
        for (int i = 0; i < interested.length; i++)
            interested[i].lifecycleEvent(event);
    }

    public void removeLifecycleListener(LifecycleListener listener) {
        synchronized (listenersLock) {
            int n = -1;
            for (int i = 0; i < listeners.length; i++) {
                if (listeners[i] == listener) {
                    n = i;
                    break;
                }
            }
            if (n < 0)
                return;
            LifecycleListener results[] =
              new LifecycleListener[listeners.length - 1];

            int j = 0;
            for (int i = 0; i < listeners.length; i++) {
                if (i != n)
                    results[j++] = listeners[i];
            }
            listeners = results;
        }
    }
}

 

 

下面,我们来看看 StandardService 类的启动方法, 看它是如何启动的

   在service真正启动时,他首先会触发一些启动前的事件,
    然后启动它自己
    接着,它会启动它关联的容器对象,
    然后,将所有它的子组件—既连接器 全部都启动 ,下面是详细的代码/

public class StandardService
        implements Lifecycle, Service, MBeanRegistration 
 {
   .............
    /**
     * The lifecycle event support for this component.
     */
    private LifecycleSupport lifecycle = new LifecycleSupport(this);
    .............
    /**
     * The set of Connectors associated with this Service.
       关联到这个Service的连接器对象.
     */
    protected Connector connectors[] = new Connector[0];
    
    public void start() throws LifecycleException {
        // Validate and update our current component state
        if (log.isInfoEnabled() && started) {
            log.info(sm.getString("standardService.start.started"));
        }
        
        if( ! initialized )
            init(); 

        // 触发启动之前的事件
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
        if(log.isInfoEnabled())
            log.info(sm.getString("standardService.start.name", this.name));

        lifecycle.fireLifecycleEvent(START_EVENT, null);  <<<<(1)
        started = true;
        // Start our defined Container first 首先启动关联的容器
        if (container != null) {
            synchronized (container) {
                if (container instanceof Lifecycle) {
                    ((Lifecycle) container).start();
                }
            }
        }

        synchronized (executors) {
            for ( int i=0; i<executors.size(); i++ ) {
                executors.get(i).start();
            }
        }

        // Start our defined Connectors second 再启动关联的连接器
        synchronized (connectors) {
            for (int i = 0; i < connectors.length; i++) {
                if (connectors[i] instanceof Lifecycle)
                    ((Lifecycle) connectors[i]).start();
            }
        }
        
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

    }

 

代码(1)处,显示出,在Service正式启动之前,它还会出发启动前的事件,我们来看看,这个方法具体做些什么.  调用LifecycleSupport 类的 fireLifecycleEvent(START_EVENT, null);方法

 

public void fireLifecycleEvent(String type, Object data) {

        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        LifecycleListener interested[] = listeners;
        for (int i = 0; i < interested.length; i++)
            interested[i].lifecycleEvent(event);

    }

 而在内部,Service启动时,这里真正调用的是类 ServerLifecycleListener的方法:

package org.apache.catalina.mbeans;





public class ServerLifecycleListener

    implements ContainerListener, LifecycleListener, PropertyChangeListener {



    public void lifecycleEvent(LifecycleEvent event) {

        Lifecycle lifecycle = event.getLifecycle();
        if (Lifecycle.START_EVENT.equals(event.getType())) {

            if (lifecycle instanceof Server) {
                createMBeans();
            }

            // We are embedded.
            if( lifecycle instanceof Service ) {
                try {
                    //Service启动时,触发的事件
                    MBeanFactory factory = new MBeanFactory();
                    createMBeans(factory);
                    createMBeans((Service)lifecycle);
                } catch( Exception ex ) {
                    log.error("Create mbean factory");
                }
            }

            /*
            // Ignore events from StandardContext objects to avoid
            // reregistering the context
            if (lifecycle instanceof StandardContext)
                return;
            createMBeans();
            */

        } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
            try {
                if (lifecycle instanceof Server) {
                    destroyMBeans((Server)lifecycle);
                }
                if (lifecycle instanceof Service) {
                    destroyMBeans((Service)lifecycle);
                }
            } catch (MBeanException t) {

                Exception e = t.getTargetException();
                if (e == null) {
                    e = t;
                }
                log.error("destroyMBeans: MBeanException", e);

            } catch (Throwable t) {

                log.error("destroyMBeans: Throwable", t);

            }
            // FIXME: RMI adaptor should be stopped; however, this is
            // undocumented in MX4J, and reports exist in the MX4J bug DB that
            // this doesn't work

        }

        if ((Context.RELOAD_EVENT.equals(event.getType()))
            || (Lifecycle.START_EVENT.equals(event.getType()))) {

            // Give context a new handle to the MBean server if the
            // context has been reloaded since reloading causes the
            // context to lose its previous handle to the server
            if (lifecycle instanceof StandardContext) {
                // If the context is privileged, give a reference to it
                // in a servlet context attribute
                StandardContext context = (StandardContext)lifecycle;
                if (context.getPrivileged()) {
                    context.getServletContext().setAttribute
                        (Globals.MBEAN_REGISTRY_ATTR,
                         MBeanUtils.createRegistry());
                    context.getServletContext().setAttribute
                        (Globals.MBEAN_SERVER_ATTR,
                         MBeanUtils.createServer());
                }
            }

        }

    }


}

 

这里简单介绍一下,Tomcat内部的启动流程, 通过观察者模式与监听器模式来作处理, 组件启动方面,在启动上级组件的同时,先启动下一级组件, (当然,在父组件内部,需要包含它所有子组件引用的一个集合).

分享到:
评论
2 楼 mercyblitz 2010-06-21  
个人感觉Tomcat扩张不易,代码风格各异。

1 楼 ilove2009 2010-06-21  
不错         

相关推荐

    tomcat 生命周期,和事件管理—— lifeCycle & event

    本文将深入探讨Tomcat的生命周期管理和事件管理,这两个概念是理解和优化Tomcat应用程序性能的关键。 首先,让我们关注Tomcat的生命周期。每个在Tomcat中部署的应用程序都有一个特定的生命周期,它由一系列的阶段...

    tomcat 架构 分析

    Tomcat的架构设计中使用了多个设计模式,例如上述生命周期管理的实现运用了状态模式,事件监听机制则运用了观察者模式。这些设计模式的使用大大增强了Tomcat的扩展性、灵活性和可维护性。 总结来说,Tomcat的架构...

    类似于Jira的基于JAVA语言写的项目管理软件,可以跟踪任务和bug的进度,实现对任务和bug全生命周期管理。

    使用JAVA语言写的项目管理软件,可以跟踪任务和bug的进度,实现对任务和bug全生命周期管理。 这个项目是很早之前开发的(大约在2008年前后),所以使用的技术是传统的JSP/Servlet+JDBC方式。虽然技术比较老了,但是...

    解读servlet生命周期

    Servlet生命周期是Java Web开发中一个关键的概念,它描述了Servlet从创建到销毁的整个过程,这个过程由Servlet容器(如Tomcat)进行管理。Servlet生命周期主要分为三个阶段:初始化阶段、运行阶段和销毁阶段。 1. ...

    tomcat6的源码

    3. **生命周期管理**:每个Tomcat组件都有自己的生命周期,包括初始化、启动、停止和销毁。源码中,这些生命周期方法的实现有助于理解Tomcat的内部工作流程。 4. **部署与加载**:Tomcat可以自动或手动部署Web应用...

    servlet生命周期详解

    Servlet生命周期是Java Web开发中的核心概念,它涵盖了Servlet从创建到销毁的整个过程,主要分为初始化...理解并掌握Servlet的生命周期对于优化性能和管理资源至关重要,尤其是在处理高并发和长时间运行的Web应用中。

    Tomcat深入剖析pdf+源码(Tomcat运行原理)

    3. **Servlet生命周期**:Servlet在Tomcat中的生命周期包括加载、初始化、服务、销毁四个阶段。Tomcat通过Servlet容器管理Servlet实例,确保其正确地创建、初始化和销毁。 4. **请求处理**:当一个HTTP请求到达时,...

    How Tomcat Works 中文版+例程源码

    3. **生命周期管理**:Tomcat按照一定的生命周期管理Servlet,包括加载、初始化、服务、销毁等阶段。每个Servlet实例都有自己的生命周期,Tomcat会根据需要创建和销毁它们。 4. **连接器(Connector)**:Tomcat...

    Tomcat 接口文档 API

    6. **Lifecycle Interfaces**: Tomcat API包含一系列生命周期接口,如Lifecycle、LifecycleListener、LifecycleState等,用于管理组件的创建、启动、停止和销毁过程。开发者可以通过实现这些接口,监控和干预Tomcat...

    Tomcat 系统架构与设计模式,第 1 部分: 工作原理1

    Tomcat 系统架构与设计模式,第 1 部分:工作原理 本文将从 Tomcat 系统架构与设计模式的角度,...在下一部分中,我们将继续探讨 Tomcat 的工作原理,包括请求处理、Servlet 生命周期管理和生命周期事件处理等方面。

    Tomcat系统架构分析

    StandardService类除了实现Service接口外,还实现了Lifecycle接口,这使得StandardService可以对下属组件进行生命周期管理,包括启动、停止、重启等。Lifecycle接口的引入是Tomcat设计中的一个重要决策,它提供了一...

    apache-tomcat-10.0.14.tar.gz

    生命周期管理: Servlet容器负责管理Servlet的生命周期,包括初始化、服务处理和销毁。 当Servlet容器启动时,它会加载并初始化配置中指定的Servlet类。在Servlet的生命周期中,容器负责调用相应的生命周期方法,...

    Servlet生命周期

    ### Servlet 生命周期详解 #### 一、概述 ...了解 Servlet 的生命周期对于更好地控制和优化 Web 应用程序至关重要...通过深入了解 Servlet 的生命周期,开发者可以更有效地管理和优化 Web 应用程序,提高其性能和稳定性。

    servlet执行过程与生命周期

    ### Servlet执行过程与生命周期详解 在探讨Servlet的执行...理解Servlet的执行过程与生命周期对Java Web开发至关重要,它不仅帮助开发者设计出更高效、更健壮的Web应用,还为解决常见的Web开发问题提供了理论基础。

    说一说servlet的生命周期

    在实际开发中,理解Servlet的生命周期对于优化性能和管理资源至关重要。例如,可以通过控制Servlet的实例化次数来减少内存消耗,或者在`init()`方法中初始化一次性的资源,在`destroy()`方法中及时释放,以确保...

    probe tomcat主机管理工具

    Servlet容器负责创建Servlet的实例,管理其生命周期,并处理来自客户端的请求。 3. **.war文件**:WAR(Web Application Archive)文件是Java Web应用程序的标准打包格式,包含了所有必要的资源,如HTML、CSS、...

    tomcat源码+文档pdf+源码解析

    1. **Catalina**:这是Tomcat的核心组件,负责Servlet容器的主要功能,如容器管理、生命周期管理和请求处理。Catalina包含Context、Host和Engine等层次结构,它们分别对应于Web应用、虚拟主机和整个服务器。 2. **...

    apache-tomcat-7.0.39

    4. **生命周期管理**:Tomcat管理Web应用程序的生命周期,包括加载、初始化、服务、停止和卸载等阶段。 5. **安全性**:Tomcat支持各种安全机制,如SSL/TLS加密、基本认证、digest认证和Form认证等。 6. **配置...

Global site tag (gtag.js) - Google Analytics