Tomcat-学习笔记

167 阅读3分钟

1.初始化流程

1.Bootstrap

初始化三个类加载器

  • commonLoader:加载 /common/* 可以被Tomcat与所有的Web应用共享的类库都在里面
  • catalinaLoader:加载 /server/* 只能被Tomcat使用的类库
  • sharedLoader:加载 /shared/* 可以被所有web程序共享的类库 对Tomcat不可见 现在根据 conf/catalina.conf 中的

common.loader=

server.loader=

shared.loader=

2.Catalina

解析Server.xml

3.StandardServer

可以初始化多个 Service

  • 1.Lifecycle:组件的生命周期,源码中有状态变更
  • 2.LifecycleBase: 为{@link Lifecycle#start()}和{@link Lifecycle#stop()}实现状态转换规则的{@link Lifecycle}接口的基本实现
  • 3.LifecycleMBeanBase:增加 MBean server
  • 4.Server:表示整个servlet容器

4.StandardService

初始化 Engine 和 Connector

5.StandardEngine

6.Connector

初始化 CoyoteAdapter 和 ProtocolHandler

7.CoyoteAdapter

使用适配器模式 负责将Tomcat Request 转成 ServletRequest

8.ProtocolHandler

处理网络协议和应用层协议 包括两个组件

1.EndPoint:实现TCP/IP 协议,包含两个Accept 和 SocketProcess

Accept:监听socket连接

SocketProcessor:处理接收的Socket请求,被提交到Executor 线程池执行

2.Processor:HTTP协议,接收来自 EndPoint 的Socket,读取字节流解析成Tomcat Request 和 Response 并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象

2.启动流程

1.Bootstrap

2.Catalina

3.StandardServer

?为什么在startInternal上加synchronized

  @Override
    protected void startInternal() throws LifecycleException {

        fireLifecycleEvent(CONFIGURE_START_EVENT, null);
        setState(LifecycleState.STARTING);

        globalNamingResources.start();

        // Start our defined Services
        synchronized (servicesLock) {
            for (int i = 0; i < services.length; i++) {
                services[i].start();
            }
        }
    }

?services[i].start() 方法又是 final synchronized 修饰

4.StandardService

启动StandardEngine

启动 Executor 线程池

? MapperListener是起什么作用的的

启动Connector

5.StandardEngine

在构造函数中设置

//管道
pipeline.setBasic(new StandardEngineValve());

? 起什么作用

 Cluster cluster = getClusterInternal();
        if (cluster instanceof Lifecycle) {
            ((Lifecycle) cluster).start();
        }
        Realm realm = getRealmInternal();
        if (realm instanceof Lifecycle) {
            ((Lifecycle) realm).start();
        }

获取Engine的子容器

 Container children[] = findChildren();
 List<Future<Void>> results = new ArrayList<>();
 for (int i = 0; i < children.length; i++) {
   results.add(startStopExecutor.submit(new StartChild(children[i])));
 }

其中 Void 是一个不可实例化的占位符类,用来保存对表示Java关键字void的对象的引用

7.StandardHost

? set error report valve 的作用

org.apache.catalina.valves.ErrorReportValve

8.StandardContext

构造函数中

pipeline.setBasic(new StandardContextValve());
broadcaster = new NotificationBroadcasterSupport();

容器组件,为特定的Web应用处理所有的客户请求

6.Connector

连接器的作用

  • 监听网络端口
  • 接受网络连接请求
  • 读取请求网络字节流
  • 根据具体应用层协议(HTTP/AJP)解析字节流,生成统一的Tomcat Request 对象
  • 将Tomcat Request 对象转成标准的ServletRequest
  • 调用Servlet容器,得到ServletResponse
  • 将ServletResponse转成Tomcat Response 对象
  • 将 Tomcat Response转成网络字节流
  • 将响应字节流写回给浏览器
1.ProtocolHandler

处理网络连接和应用层协议

1. EndPoint
ServerSocketChannel serverSock
ConcurrentLinkedQueue 无界安全的队列

Selector 放入 ConcurrentLinkedQueue

NioSelectorPool //线程安全的非阻塞 selector 池

通信监听接口,具体Socket接收和发送处理器,实现TCP/IP协议的 具体实现 为AbstractEndpoint,它包含三个子类

  • NioEndpoint

                // Create worker collection
                if ( getExecutor() == null ) {
                    createExecutor();
                }
                //初始化连接限制
                initializeConnectionLatch();
    
                // Start poller threads 轮询器启动线程 长度是2
                pollers = new Poller[getPollerThreadCount()];
                for (int i=0; i<pollers.length; i++) {
                    pollers[i] = new Poller();//这里会有多个 selector
                    Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i);
                    pollerThread.setPriority(threadPriority);
                    pollerThread.setDaemon(true);
                    pollerThread.start();//启动socket处理socket
                }
                //启动接收socket线程
                startAcceptorThreads();
    

1.接收

    protected final void startAcceptorThreads() {
        // count = 1 接收线程数
        int count = getAcceptorThreadCount();
        acceptors = new Acceptor[count];//接收类

        for (int i = 0; i < count; i++) {
            acceptors[i] = createAcceptor();
            String threadName = getName() + "-Acceptor-" + i;
            acceptors[i].setThreadName(threadName);
            Thread t = new Thread(acceptors[i], threadName);
            t.setPriority(getAcceptorThreadPriority());
            t.setDaemon(getDaemon());
            t.start();
        }
    }
  • Nio2Endpoint
  • AprEndpoint

7.CoyoteAdapter

8.ProtocolHandler

4个容器 Engine:表示引擎,用来管理多个虚拟站点 Host:表示一个虚拟主机,或者站点 Context:表示一个web应用程序 Wrapper:表示一个Servlet

server.xml

<Server> //顶层组件,可以包括多个Service
 <Service>//顶层组件,可包含一个Engine,多个连接器
  <Connector>//连接器组件,代表通信接口
  </Connector>
  <Engine>//容器组件,一个Engine处理Service中的所有请求,包含多个Host
   <Host> //容器组件,处理特定的Host下客户请求,可包含多个Context
    <Context> //容器组件,为特定的Web应用处理所有的客户请求
    </Context>
   </Host>
  </Engine>
 </Service>
</Server>