Tomcat学习笔记(二)——整体结构及组件简介

在深入学习Tomcat之前,先了解一下它的整体结构以及各个组件,这对以后看源码会非常的有帮助。本笔记的主要参考资料是《Tomcat内核设计剖析》。


Tomcat整体结构



首先看下Tomcat源码中conf目录下的server.xml的层级结构,如下所示。
<?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" />
    <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>

从上面xml配置文件中可以看出,Tomcat的整体结构与下图十分的相似,但是与下图相比还是少了Context组件。在Context组件中包含了Wrapper组件,Wrapper组件里看见了非常熟悉的Servlet。
这就是Tomcat的整体结构了。首先简单了解一下每个组件的作用,每个组件具体的功能以及源码实现后续再进行研究。
在这里插入图片描述


1.Server组件

从Tomcat层次结构图可以看见,Server是最顶层的组件。它代表着Tomcat运行实例并且在一个JVM中只会包含一个Server。Server组件中还包含Listener组件、GlobalNamingResourcs组件和核心组件Service。引入Listener组件是为了方便扩展,引入GlobalNamingResourcs时为了方便在Tomcat中集成JNDI


2.Service组件

Service是服务的抽象,它代表请求从接收到处理的所有组件的集合。在设计上Server组件可以包含多个Service组件。如下xml所示,每个Service组件都包含了若干用于接收客户端消息的Connector组件和处理请求的Engine组件。其中Connector组件定义了通信协议,不同的Connector组件使用不同的协议。Engine组件用来处理请求。若干Connector组件和一个客户端请求处理组件Engine组成的集合即为Service组件。另外,Service组件还包含Executor组件,每个Executor组件是一个线程池,它可以为Service内所有组件提供线程池执行任务。

  <Service name="Catalina">
  	<!--定义不同的通信协议-->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
     <!--用于处理请求-->
    <Engine name="Catalina" defaultHost="localhost">
    	...
    </Engine>
  </Service>

3.Connector组件

Connector主要的职责就是接收客户端连接并接收消息报文,消息报文经由它解析后送往容器中处理。因为存在不同的通信协议,所以Tomcat可以配置不同的Connector组件。目前Tomcat包含Http和AJP两种协议的Connector。

  	<!--定义不同的通信协议-->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

对于Http协议Connector组件内部会根据网络I/O的不同方式分为BIO、NIO、APR、AIO四种。Tomcat7之前默认使用BIO、8之后默认采用NIO模式。


4.Engine组件

Tomcat的内部有4个级别的容器,分别是Engine、Host、Context和Wrapper。Engine代表全局Servlet引擎,每个Service组件只能包含一个Engine组件。Engine可以包含多个Host组件。它还包含以下组件:

  • Listener组件:某些与Engine容器相关的监听
  • AccessLog组件:记入客户端的访问日志
  • Cluster组件:提供集群功能,可以将Engine容器需要共享的数据同步到集群中的其他Tomcat实例上
  • Pipline组件:Engine组件对请求进行处理的管道
  • Realm组件:提供了Engine容器级别的用户-密码-权限的数据对象,配合资源认证模块使用

5.Host组件

Host组件代表虚拟主机,这些虚拟主机可以存放若干Web应用的抽象(Context容器)。它还包含以下组件:

  • Listener组件:某些与Engine容器相关的监听
  • AccessLog组件:记入访问该虚拟主机上Web应用的客户端的访问日志
  • Cluster组件:提供集群功能,可以将Host容器需要共享的数据同步到集群中的其他Tomcat实例上
  • Pipline组件:Host组件对请求进行处理的管道
  • Realm组件:提供了Host容器级别的用户-密码-权限的数据对象,配合资源认证模块使用

6.Context组件

Context组件是Web应用的抽象,我们开发的Web应用部署到Tomcat后运行时就会转化成Context对象。它包含了各种静态资源、若干Servlet(Wrapper容器)以及各种其他动态资源。它主要包括如下组件。

  • Listener组件:可以在Tomcat生命周期中完成某些Context容器相关工作的监听器。
  • AccessLog组件:客户端的访问日志,对该Web应用的访问都会被记录。
  • Pipeline组件:Context容器对请求进行处理的管道。
  • Realm组件:提供了Context容器级别的用户-密码-权限的数据对象,配合资源认证模块使用。
  • Loader组件:Web应用加载器,用于加载Web应用的资源,它要保证不同Web应用之间的资源隔离。
  • Manager组件:会话管理器,用于管理对应Web容器的会话,包括维护会话的生成、更新和销毁。
  • NamingResource组件:命名资源,它负责将Tomcat配置文件的server.xml和Web应用的context.xml资源和属性映射到内存中。
  • Mapper组件:Servlet映射器,它属于Context内部的路由映射器,只负责该Context容器的路由导航。
  • Wrapper组件:Context的子容器。

7.Wrapper组件

Wrapper容器是Tomcat中4个级别的容器中最小的,与之相对应的是Servlet,一个Wrapper对应一个Servlet。它包含如下组件。

  • Servlet组件:Servlet即Web应用开发常用的Servlet,我们会在Servlet中编写好请求的逻辑处理
  • ServletPool组件:Servlet对象池,当Web应用的Servlet实现了SingleThreadModel接口时则会在Wrapper中产生一个Servlet对象池。线程执行时,需先从对象池中获取到一个Servlet对象,ServletPool组件能保证Servlet对象的线程安全。
  • ServletPool组件:Servlet对象池,当Web应用的Servlet实现了SingleThreadModel接口时则会在Wrapper中产生一个Servlet对象池。线程执行时,需先从对象池中获取到一个Servlet对象,ServletPool组件能保证Servlet对象的线程安全。

请求处理的整体流程

在这里插入图片描述这里假定Tomcat作为专门处理HTTP的Web服务器,而且使用阻塞I/O方式接受客户端的连接。下面介绍请求流转的具体过程。
① 当Tomcat 启动后,Connector组件的接收器(Acceptor)将会监听是否有客户端套接字连接并接收Socket。
② 一旦监听到客户端连接,则将连接交由线程池Executor处理,开始执行请求响应任务。
③ Http11Processor组件负责从客户端连接中读取消息报文,然后开始解析HTTP的请求行、请求头部、请求体。将解析后的报文封装成Request 对象,方便后面处理时通过Request对象获取HTTP协议的相关值。
④ Mapper组件根据HTTP协议请求行的URL属性值和请求头部的Host属性值匹配由哪个Host容器、哪个Context容器、哪个Wrapper容器处理请求,这个过程其实就是根据请求从Tomcat中找到对应的Servlet。然后将路由的结果封装到Request对象中,方便后面处理时通过Request对象选择容器。
⑤ CoyoteAdaptor组件负责将Connector组件和Engine容器连接起来,把前面处理过程中生成的请求对象Request和响应对象Response传递到Engine容器,调用它的管道。
⑥ Engine容器的管道开始处理请求,管道里包含若干阀门(Valve),每个阀门负责某些处理逻辑。这里用xxxValve代表某阀门,我们可以根据自己的需要往这个管道中添加多个阀门,首先执行这个xxxValve,然后才执行基础阀门EngineValve,它会负责调用Host容器的管道。
⑦ Host容器的管道开始处理请求,它同样也包含若干阀门,首先执行这些阀门,然后执行基础阀门HostValve,它继续往下调用Context容器的管道。
⑧ Context容器的管道开始处理请求,首先执行若干阀门,然后执行基础阀门ContextValve,它负责调用Wrapper容器的管道。
⑨ Wrapper容器的管道开始处理请求,首先执行若干阀门,然后执行基础阀门WrapperValve,它会执行该Wrapper容器对应的Servlet对象的处理方法,对请求进行逻辑处理,并将结果输出到客户端。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值