Tomcat整体架构

845 阅读3分钟

总体架构

核心功能:

  • 处理socket连接,负责将网络字节流与Request和Response对象的转化;
  • 加载和管理Servlet,以及具体处理Request请求。

Tomcat支持的io模型有: NIO、NIO2、APR Tomcat支持的应用层协议有: http1.1 ajp http2.0

tomcat最顶层是server,一个server有多个service,一个service有多个连接器和一个容器,连接器和容器之间通过ServletRequest和ServletResponse通信。 高层示意图

通过组合模式、模板方法、观察者模式和骨架抽象类,tomcat定义了基类LifeCycleBean实现LifeCycle接口,把公共的逻辑,生命周期状态转变和维护、生命事件的触发和监听器的添加删除,子类负责实现自己的init、stop和start等方法。

  • tomcat自定义了监听器
  • @WebListener注解,定义自己的监听器

StandardServer、StandardService 等是 Server 和 Service 组件的具体实现类,它们都继承了 LifecycleBase。

StandardEngine、StandardHost、StandardContext 和 StandardWrapper 是相应容器组件的具体实现类,因为它们都是容器,所以继承了 ContainerBase 抽象基类,而 ContainerBase 实现了 Container 接口,也继承了 LifecycleBase 类,它们的生命周期管理接口和功能接口是分开的。

连接器Connector

连接器进一步细化:

  • 监听网络端口
  • 接受网络请求
  • 读取网络字节流
  • 根据应用层协议解析字节流,生成统一的tomcat request和tomcat response对象
  • 将tomcat request对象转成servletRequest
  • 调用servlet容器,得到servletResponse
  • 将servletResponse转成tomcat response
  • 将tomcat response转成网络字节流
  • 将响应字节流写回给浏览器

按照高内聚的功能划分:

  • 网络通信
  • 应用层协议解析
  • tomcat request/response与servlet request/response的转换

组件通过接口交互,好处是封装变化。

Endpoint负责提供字节流给Processor,Processor负责提供tomcat request对象给Adapter,Adapter负责提供Servlet Request给容器。

其中Endpoint和Processor抽象组装在一起形成了ProtocolHandler组件。 连接器组件

ProtocolHandler

Endpoint

接口,抽象实现类是AbstractEndpoint,具体子类在NioEndpoint和Nio2Endpoint,其中两个重要组件:Acceptor和SocketProcessor。

Acceptor用于监听Socket连接请求,SocketProcessor用于处理收到的Socket请求,提交到线程池Executor处理。

Processor

接收Endpoint的socket,读取字节流解析成tomcat request和response,通过adapter将其提交到容器处理。 Processor的具体实现类AjpProcessor、Http11Processor实现了特定协议的解析方法和请求处理方式。 连接器

Endpoint接收到socket连接后,生成一个socketProcessor交给线程池处理,run方法会调用Processor解析应用层协议,生成tomcat request后,调用adapter的service方法。

Adapter

ProtocolHandler接口负责解析请求生成tomcat requst,CoyoteAdapter的service方法,将Tomcat Request对象,转成ServletRequest,再调用service方法。

容器Container

容器的层次结构

父子关系的Engine、Host、Context、Wrapper和Servlet。 Context表示web应用程序、wrapper表示servlet、context有多个wrapper,host也有多个context。

容器

Host 代表的是一个虚拟主机,或者说一个站点,可以给 Tomcat 配置多个虚拟主机地址,而一个虚拟主机下可以部署多个 Web 应用程序;Engine 表示引擎,用来管理多个虚拟站点,一个 Service 最多只能有一个 Engine。

请求路径

容器通过Pipeline-Valve责任链,对请求一次处理,invoke处理方法,

每个容器都有一个Pipeline,触发第一个Valve,这个容器的valve都会被调到,不同容器之间通过Pipeline的getBasic方法,负责调用下层容器的第一个Valve。

pipeline

整个调用连由连接器中的adapter触发,调用engine中的第一个Valve。

// Calling the container
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);

wrapper容器的最后一个valve创建一个filter链,并调用doFilter方法,最终会调用到servlet的service方法。

final class StandardWrapperValve
    extends ValveBase {
    
   @Override
      public final void invoke(Request request, Response response)
          throws IOException, ServletException {
          // ...
          
          ApplicationFilterChain filterChain =
                ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);

        // Call the filter chain for this request
        // NOTE: This also calls the servlet's service() method
        Container container = this.container;
        try {
            if ((servlet != null) && (filterChain != null)) {
                // Swallow output if needed
                if (context.getSwallowOutput()) {
                    try {
                        SystemLogHandler.startCapture();
                        if (request.isAsyncDispatching()) {
                            request.getAsyncContextInternal().doInternalDispatch();
                        } else {
                        
                        // dofilter
                            filterChain.doFilter(request.getRequest(),
                                    response.getResponse());
                        }
                    } finally {
                        String log = SystemLogHandler.stopCapture();
                        if (log != null && log.length() > 0) {
                            context.getLogger().info(log);
                        }
                    }
                } else {
                    if (request.isAsyncDispatching()) {
                        request.getAsyncContextInternal().doInternalDispatch();
                    } else {
                    	// dofilter
                        filterChain.doFilter
                            (request.getRequest(), response.getResponse());
                    }
                }

            }
        } catch() {
        // ...
        }
    }
}

ServletContext是tomcat中的一个成员变量,spring中的ApplicationContext是servlet规范中的ServletContext属性。