Tomcat架构分析

整体架构

首先,认识一下tomcat核心组件:serverserviceconnectorcontainer/engine

  • server:最顶层的容器,代表着整个服务器,掌管整个Tomcat的生死大权。一个 server 可以有多个 service
  • service:一个 service 有多个connector和一个container
  • connector:监听网络端口,接受网络请求
  • container:接收connector发来的request请求,并进行业务处理

包含关系如下图所示:
在这里插入图片描述

上面所说的包含关系,都可以在Tomcat的conf目录下server.xml中看出。下面是删除了注释的server.xml(Tomcat版本为8.0.47)

<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  
  <Service name="Catalina">
  
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
    
  </Service>
</Server>

通过下面这张结构图,可以更加清晰的理解配置文件server.xml
在这里插入图片描述
Host

  • 一个 Host 配置即为一个虚拟主机,可以通过appBase属性配置web项目的目录
  • appBase属性所指向的目录应该是准备用于存放一组 Web 应用程序的目录,而不是具体某个 Web 应用程序的目录本身

Context

  • 具体的Web 应用程序,对应着平时开发的一套web程序
8005端口
 - tomcat监听的关闭端口,就是说这个端口负责监听关闭tomcat的请求。
 - 当执行shutdown.sh关闭tomcat时,就是通过8005端口发送SHUTDOWN命令。
 - 用telnet向8005端口发送SHUTDOWN命令,也可以关闭tomcat,如果这个端口没被监听,那么shutdown.sh脚本就是无效的。

8009端口
 - AJP协议端口
 - AJP建立TCP连接后一般长时间保持,从而减少HTTP反复进行TCP连接和断开的开销

8080端口
 - connector监听HTTP请求的端口

Connector架构

在这里插入图片描述
Connector就是使用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型,比如:Http11Protocol使用的是普通Socket来连接的,Http11NioProtocol使用的是NioSocket来连接的。

其中ProtocolHandler由包含了三个部件:Endpoint、Processor、Adapter。

  • Endpoint:处理底层Socket的网络连接
  • Processor:将Endpoint接收到的Socket封装成Tomcat Request
  • Adapter:将Tomcat Request封装成ServletRequest,给容器处理

Socket封装成Tomcat Request细节流程如下所示:
在这里插入图片描述

Container架构

在这里插入图片描述

  • Engine:容器,一个Service最多只能有一个Engine
  • Host:虚拟主机
  • Context:应用程序
  • Wrapper:每一Wrapper封装着一个Servlet

看到这里我们知道Container是什么,但还是不知道Container是如何处理请求的,以及处理完之后是如何将处理完的结果返回给Connector的。

别急,下边就开始探讨一下Container是如何进行处理的。

Container处理流程

容器通过Pipeline-Valve责任链模式来处理请求

但是,Pipeline-Valve使用的责任链模式和普通的责任链模式有些不同,区别主要有以下两点:

  1. 每个Pipeline都有特定的Valve,而且是在管道的最后一个执行,这个Valve叫做BaseValve,BaseValve是不可删除的
  2. 在上层容器的管道的BaseValve中会调用下层容器的管道

Container包含四个子容器,而这四个子容器对应的BaseValve分别是:

  • StandardEngineValve
  • StandardHostValve
  • StandardContextValve
  • StandardWrapperValve

Pipeline的处理流程图如下:
在这里插入图片描述

  1. Connector在接收到请求后会首先调用最顶层容器的Pipeline来处理,这里的最顶层容器的Pipeline就是EnginePipeline(Engine的管道)。

  2. 在Engine的管道中依次会执行EngineValve1、EngineValve2等等,最后会执行StandardEngineValve,在StandardEngineValve中会调用Host管道,然后再依次执行Host的HostValve1、HostValve2等,最后在执行StandardHostValve,然后再依次调用Context的管道和Wrapper的管道,最后执行到StandardWrapperValve。

  3. 当执行到StandardWrapperValve的时候,会在StandardWrapperValve中创建FilterChain,并调用其doFilter方法来处理请求,这个FilterChain包含着我们配置的与请求相匹配的FilterServlet,其doFilter方法会依次调用所有的Filter的doFilter方法和Servlet的service方法,这样请求就得到了处理。

  4. 当所有的Pipeline-Valve都执行完之后,并且处理完了具体的请求,这个时候就可以将返回的结果交给Connector了,Connector在通过Socket的方式将结果返回给客户端。

结束啦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值