一、介绍
1、Tomcat内核高度抽象,则它可以看成由连接器(Connector)组件和容器(Container)组件组成,其中Connector组件负责在服务器端处理客户端连接,包括接收客户端连接、接收客户端的消息报文以及消息报文的解析等工作,而Container组件则负责对客户端的请求进行逻辑处理,并把结果返回给客户端。
2、Container组件实包括4个级别的容器:Engine组件、Host组件、Context组件和Wrapper组件,容器也是整个Tomcat的核心。
二、tomcat server.xml 中组件说明
<? xml version ='1.0' encoding='utf-8'?>
<Server>
<Service>
<Executor/>
<Connector/>
<Engine>
<Cluster/>
<Realm/>
<Host>
<Context/>
</Host>
</Engine>
</Service>
</Server>
1、Server组件
- Server是最顶级的组件,它代表Tomcat的运行实例,在一个JVM中只会包含一个Server。
- 在Server的整个生命周期中,不同阶段会有不同的事情要完成。
- 为了方便扩展,它引入了监听器方式,所以它也包含了Listener组件。
- 为了方便在Tomcat中集成JNDI,引入了GlobalNamingResources组件。同时,还包含了Service核心组件。
2、Service组件
- Service是服务的抽象,它代表请求从接收到处理的所有组件的集合。
- Server组件可以包含多个Service组件。
- 每个Service组件都包含了若干用于接收客户端消息的Connector组件和处理请求的Engine组件。若干Connector组件和一个客户端请求处理组件Engine组成的集合即为Service。
- 不同的Connector组件使用不同的通信协议,如HTTP协议和AJP协议,当然还可以有其他的协议A和协议B。
- Service组件还包含了若干Executor组件,每个Executor都是一个线程池,它可以为Service内所有组件提供线程池执行任务。
3、Connector组件
- Connector主要的职责就是接收客户端连接并接收消息报文,消息报文经由它解析后送往容器中处理。
- 因为存在不同的通信协议,例如HTTP协议、AJP协议等,所以需要不同的Connector组件,每种协议对应一个Connector组件,目前Tomcat包含HTTP和AJP两种协议的Connector。
- Connector组件的内部实现也会根据网络I/O的不同方式而不同分为阻塞I/O和非阻塞I/O。
4、BIO Connector组件 包含:
- Http11Protocol组件,是HTTP协议1.1版本的抽象,它包含接收客户端连接、接收客户端消息报文、报文解析处理、对客户端响应等整个过程。
a: 它主要包含JIoEndpoint组件和Http11Processor组件。启动时,JIoEndpoint组件内部的Acceptor组件将启动某个端口的监听,一个请求到来后将被扔进线程池Executor,线程池进行任务处理,处理过程中将通过Http11Processor组件对HTTP协议解析并传递到Engine容器继续处理。
- Mapper组件,客户端请求的路由导航组件,通过它能对一个完整的请求地址进行路由,能通过请求地址找到对应的Servlet。
- CoyoteAdaptor组件,一个将Connector和Container适配起来的适配器。
5、NIO Connector组件 包含:
- 在非阻塞I/O方式下,Connector的结构类似阻塞模式,Http11Protocol组件改成Http11NioProtocol组件,JIoEndpoint组件改成NioEndpoint, Http11Processor组件改成Http11NioProcessor组件,组件的功能类似。
- 多了一个Poller组件,它的职责是在非阻塞I/O方式下轮询多个客户端连接,不断检测、处理各种事件,例如不断检测各个连接是否有可读,对于可读的客户端连接则尝试进行读取并解析消息报文。
6、Engine组件
- Engine代表全局Servlet引擎,每个Service组件只能包含一个Engine容器组件,但Engine组件可以包含若干Host容器组件。
- Listener组件:可以在Tomcat生命周期中完成某些Engine容器相关工作的监听器。
- AccessLog组件:客户端的访问日志,所有客户端访问都会被记录。
- Cluster组件:它提供集群功能,可以将Engine容器需要共享的数据同步到集群中的其他Tomcat实例上。
- Pipeline组件:Engine容器对请求进行处理的管道
- Realm组件:提供了Engine容器级别的用户-密码-权限的数据对象,配合资源认证模块使用。
7、Host组件
- Tomcat中Host组件代表虚拟主机,这些虚拟主机可以存放若干Web应用的抽象(Context容器)。
- Listener组件:可以在Tomcat生命周期中完成某些Host容器相关工作的监听器
- AccessLog组件:客户端的访问日志,对该虚拟主机上所有Web应用的访问都会被记录。
- Cluster组件:它提供集群功能,可以将Host容器需要共享的数据同步到集群中的其他Tomcat实例上。
- Pipeline组件:Host容器对请求进行处理的管道
- Realm组件:提供了Host容器级别的用户-密码-权限的数据对象,配合资源认证模块使用
8、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容器的路由导航。
9、Wrapper组件
- Wrapper容器是Tomcat中4个级别的容器中最小的,与之相对应的是Servlet,一个Wrapper对应一个Servlet。
- Servlet组件:Servlet即Web应用开发常用的Servlet,我们会在Servlet中编写好请求的逻辑处理。
- ServletPool组件:Servlet对象池,当Web应用的Servlet实现了SingleThreadModel接口时则会在Wrapper中产生一个Servlet对象池。线程执行时,需先从对象池中获取到一个Servlet对象,ServletPool组件能保证Servlet对象的线程安全。
- Pipeline组件:Wrapper容器对请求进行处理的管道。
三、请求处理的过程
1、以Tomcat作为专门处理HTTP的Web服务器,而且使用阻塞I/O方式接受客户端的连接为例子。
2、Tomcat 启动后,Connector组件的接收器(Acceptor)将会监听是否有客户端套接字连接并接收Socket。
3、一旦监听到客户端连接,则将连接交由线程池Executor处理,开始执行请求响应任务。
4、Http11Processor组件负责从客户端连接中读取消息报文,然后开始解析HTTP的请求行、请求头部、请求体。将解析后的报文封装成Request对象,方便后面处理时通过Request对象获取HTTP协议的相关值。
5、Mapper组件根据HTTP协议请求行的URL属性值和请求头部的Host属性值匹配由哪个Host容器、哪个Context容器、哪个Wrapper容器处理请求,这个过程其实就是根据请求从Tomcat中找到对应的Servlet。然后将路由的结果封装到Request对象中,方便后面处理时通过Request对象选择容器。
6、CoyoteAdaptor组件负责将Connector组件和Engine容器连接起来,把前面处理过程中生成的请求对象Request和响应对象Response传递到Engine容器,调用它的管道
7、 Engine容器的管道开始处理请求,管道里包含若干阀门(Valve),每个阀门负责某些处理逻辑。这里用xxxValve代表某阀门,可以根据自己的需要往这个管道中添加多个阀门,首先执行这个xxxValve,然后才执行基础阀门EngineValve,它会负责调用Host容器的管道。
8、Host容器的管道开始处理请求,它同样也包含若干阀门,首先执行这些阀门,然后执行基础阀门HostValve,它继续往下调用Context容器的管道。
9、 Context容器的管道开始处理请求,首先执行若干阀门,然后执行基础阀门ContextValve,它负责调用Wrapper容器的管道。
10、Wrapper容器的管道开始处理请求,首先执行若干阀门,然后执行基础阀门WrapperValve,它会执行该Wrapper容器对应的Servlet对象的处理方法,对请求进行逻辑处理,并将结果输出到客户端。