Tomca容器 ContainerBase 解析

Tomcat的核心作用是Servlet容器,

Tomcat中Engine,Host,Context,Wrapper有一个骨架类org.apache.catalina.core.ContainerBase,

ContainerBase

protected final HashMap<String, Container> children = new HashMap<>();
protected Container parent = null;
protected Pipeline pipeline = new StandardPipeline(this);
protected ArrayList<ContainerListener> listeners = new ArrayList<ContainerListener>();

protected synchronized void startInternal() throws LifecycleException {
    ...
    //后台共享线程在容器启动后调用.
    threadStart();
}   
protected void threadStart() {
    ...
    threadDone = false;
    String threadName = "ContainerBackgroundProcessor[" + toString() + "]";
    thread = new Thread(new ContainerBackgroundProcessor(), threadName);
    thread.setDaemon(true);
    thread.start();
}
 public void backgroundProcess() {      
    cluster.backgroundProcess();

    loader.backgroundProcess();

    manager.backgroundProcess();

    Realm realm = getRealmInternal();

    realm.backgroundProcess();

    Valve current = pipeline.getFirst();
    while (current != null) {   
        current.backgroundProcess();    
        current = current.getNext();
    }
        fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null);
 }

从上面源码我们可以看到, 容器包含父子关系(有children容器),
每个容器内部都有一个pipeline,请求在各容器内部管道中的阀门间传递.
ContainerBase.backgroundProcess()中可以看到如下任务:

(1)Cluster的后台任务:发送心跳包,监听集群部署的改变(Engine和Host包含)
(2)Realm的后台任务,如果子类定义实现了话(Engine,Host,Context包含);
(3)整个Valve链中每个Valve的后台任务,
(4)Loader的后台任务,Context的reload设置为true,将会在后台任务中周期性检查资源(包括WEB-INF/classes下的类文件和WEB-INF/lib中的jar包)是否修改,如果发现修改将调用StandardContext.reload()进行重启
(5)Manager的后台任务,ManagerBase实现了会话管理的一个重要任务:将所有超时的会话进行失效,并进行清理(从Manager的session集合中删除);
(6)WebResourceRoot的后台任务,上面Loader也是基于WebResourceRoot的,但WebResourceRoot除了class文件和jar包之外,还包括Web应用中其他所有资源的抽象,它的后台任务主要是清除过时的缓存记录。
(7)启动子容器任务线程池. 子容器的启动是通过线程池来实现的.

//org.apache.catalina.core.ContainerBase#startInternal
  Container children[] = findChildren();
   List<Future<Void>> results = new ArrayList<Future<Void>>();
   for (int i = 0; i < children.length; i++) {
       results.add(startStopExecutor.submit(new StartChild(children[i])));
   }

   boolean fail = false;
   for (Future<Void> result : results) {
    result.get();
   }

Tomcat中的运行时监控/管理和JMX

如果查看你就会发现组件并不是直接派生子LifecycleBase的,而是派生自LifecycleMBeanBase

public abstract class ContainerBase extends LifecycleMBeanBase{}

public abstract class LifecycleMBeanBase extends LifecycleBase
        implements MBeanRegistration 
        {}

这个类除了继承了Lifecyle这条设计路线外还引入了JMX的功能。简单来说,就是Tomcat为了使用JMX提供的监控和管理能力,其组件可以作为MBean可以注册到MBeanServer中,从而我们可以在运行时对Tomcat进行管理和监控。

注入过程:

 @Override
  protected void initInternal() throws LifecycleException {

      // If oname is not null then registration has already happened via
      // preRegister().
      if (oname == null) {
          mserver = Registry.getRegistry(null, null).getMBeanServer();

          oname = register(this, getObjectNameKeyProperties());
      }
  }

猜你喜欢

转载自blog.csdn.net/yangsnow_rain_wind/article/details/80053530