1)server
服务器可以描述为这样一个应用:接收客户端发来的请求数据并进行解析,完成相关业务处理,然后把处理结果作为相应返回给客户端。
通常我们可以使用serversocket监听指定端口来实现该功能
2)Connection和Container(Engine)
当我们将请求监听和请求处理放在一起的时候扩展性就很差。比如当我们想适配多种网络协议,但是请求处理却相同的时候。
处理方案就是:将网络协议和请求处理从概念上分开。Connection负责开启socket并监听客户端请求、返回响应数据;Container(Engine)负责具体的请求处理。
3)Service
上述方案的缺陷就是无法很好的判断Connection由哪个Container(Engine)来处理。
采用service方案,一个server包含多个service(它们相互独立),一个service包含多个Connection和一个Container,这样,connection的请求只能由该container来处理
由于Container表示一个更加通用的概念,为了与Tomcat组件命名一致,将Container重新命名为Engine,用于表示整个servlet引擎
4)Context
上述解决了网络协议和容器的解耦。下面我们需要在Engine中支持管理web应用。当接收到Connection请求时,能够找到一个合适的Web应用来处理。Context就代表一个Web应用
5)Host
为了提供对多个域名的服务,我们可以将每个域名视为一个虚拟的主机。在每个Host下包含多个Context
6)Wrapper
在一个Web应用中,可以包含多个servlet实例来处理不同链接的请求。因此,需要一个组件概念来表示Servlet定义,在Tomcat中servlet定义被称为Wrapper
7)Container
容器代表一类组件,这类组件的作用就是接收客户端请求并返回响应数据,具体操作委派到子组件完成。
Engine、Host、Context、Wrapper均继承自Container
8)LifeCycle
所有的组件均存在启动、停止等生命周期方法,拥有生命周期管理的特性,我们将这个抽取出来作为接口LifeCycle,定义生命周期管理的核心方法。
9)Executor
tomcat的并发,提供了Executor接口来表示一个可以在组件间共享的线程池。该接口同样继承LifeCycle接口
共享范围:Executor由Service维护,因此同一个Service中的组件可以共享一个线程池
10)Bootstrap和Catalina
Catalina提供一个shell程序,用于解析service.xml创建各个组件。同时负责启动、停止应用服务器
Bootstrap作为应用服务器启动入口。Bootstrap负责创建Catalina,根据执行参数调用Catalina相关方方法完成对应用服务器的操作
总结:* Server 表示整个servlet容器,因此Tomcat容器中只有一个Server实例
* Service 表示一个或多个Connector的集合。这些Connector共享同一个Container来处理其他请求。在一个Server中可以包含多个Service,这些Service相互独立
* Connector Tomcat连接器,用于监听并转换为Socket请求,将该请求交由Container处理,支持不同的协议及不同IO方式
* Container 表示能够接收请求并返回响应的一类对象。在Tomcat中存在不同级别的容器:Engine、Host、Context、Wrapper
* Engine 表示整个Servlet引擎,Engine为最高级别的容器。尽量Engine不是直接处理请求的容器却是获得目标容器的入口
* Host 表示Engine中的虚拟机,与一个服务器的网络名有关,如域名等。客户端可以使用这个网络名连接服务器,这个名称必须要在DNS服务器上注册
* Context 用于表示ServletContext,在Servlet规范中,一个ServletContext表示一个Web应用
* Wrapper 表示Web应用中定义的Servlet
* Executor 表示Tomcat组件间可以共享的线程池
2.请求处理过程从本质上讲,应用服务器的处理开始于监听的Socket端口接收到数据,结束于将处理结果写入Socket输出流
* 应用服务器将请求按照既定协议进行读取,并将其封装为与具体协议无关的请求体
* 按照请求映射规则将请求定位到具体的处理单元(使用框架的话SpringMVC等则会将请求匹配到Servlet下的一个控制器)
* 业务处理结束,将结果封装到一个与协议无关的响应对象
3.Tomcat类加载方案应用服务器通常会创建类加载器以实现更灵活的控制。
* 隔离性:Web应用类库互相隔离,避免依赖库或应用包相互影响。设想有两个应用,一个采取Spring2.X,一个采取Spring4.X,而应用服务器使用同一个类加载器,那么应用之间会因为jar包覆盖导致无法启动
* 灵活性:Web应用之间的类加载器相互独立,我们就能只针对一个Web应用重新部署
* 性能:每个Web应用都有一个类加载器,则Web应用在加载类时,不会搜索其他Web应用包含的jar包,性能自然高
1)Common 位于Tomcat顶层的公共类加载器,默认指向Tomcat_home/lib下的包
2)Catalina 用于加载Tomcat应用服务器的类加载器,路径为server.loader,默认为空
3)Shared 所有web应用的父加载器,路径为shared.loader,默认为空
4)Web 加载WEB-INF/classes下的未压缩的class、资源文件及WEB-INFO/lib下的jar包,该类加载器只对当前web应用可见
在catalina.jar org.apache.catalina.loader包下可以看到关于ClassLoader的实现
4.通过server.xml来查看Tomcat各组件之间的关系我们在Eclipse中创建一个web项目,springweb,并在Eclipse中关联Tomcat8.5,并在Tomcat中关联springweb,启动Tomcat,可以看到生成的server.xml如下所示:
由上可知,Tomcat结构图可如下所示:
* Tomcat只要一个Server,一个Server可以有多个Service,一个Service可以有多个Connection和Container
* Server掌管整个Tomcat的生死大权
* Service是对外提供服务的
* Connector用于接收请求并将请求封装成Request和Response来具体处理
* Container用于管理和封装Servlet,以及处理具体Request请求
参考:Tomcat架构解析(刘光瑞)