Tomcat源码分析 -- 2

2019-03-07  本文已影响0人  sschrodinger

Tomcat源码分析 -- 2

sschrodinger

2018/12/19


参考



tomcat 总体架构


构想一个最简单的服务器,UML 类图如下:

简单服务器

但是在实际的服务器中,我们将请求监听和请求处理放在一起的拓展性很差,我们有可能使用 HTTP 协议为客户端提供服务,也可能使用其他协议为客户端提供服务,为了最大程度的解耦,我们将网络协议与请求处理从概念上分离,如下图:

组件分离

其中,Connector 是负责开启 Socket 并监听客户端请求、返回响应数据的组件。Container 负责处理具体的请求。他们这两个部件都有自己的 start() 和 stop() 方法来加载和释放自己维护的资源。

如果一个 Server 可以包含多个 Connector 和 Container,建立 Connector 和 Container 之间的映射就很重要,Tomcat 没有选择维护一个复杂的映射规则来解决这个问题,而是在这两个部件之间增加了一个中间层 service,如下图所示:

增加service

一个 Server 包含多个 Service(他们相互独立,只是共享一个JVM以及系统类库)。一个 Service 负责维护多个 Connector 和一个 Container。举例来说,一个 Tomcat 服务器可能同时使用了 8080 端口监听 Http 请求, 一个 8005 端口管理 Tomcat 服务器,这样就需要两个 Connector 来处理连接。

在真实的 Tomcat 中,Container 是一个更加宽泛的概念,为了不重名,我们将这的 Containner 改名成 Engine,如下所示:

engine

在 Tomcat 中,使用 Context 来代表一个具体的应用,所谓的具体的应用,就是一个动态 web 程序。一个 Engine 可以包含多个 Context。如下图所示:

context

继续扩展,可能一台主机承担了多个域名的服务,我们可以寄那个每个域名视为一个虚拟的主机,在每个虚拟的主机上包含多个 web 应用,在 Engine 和 Host 之间增加一个 Host 层。

host

note

  • 在 Tomcat 中,Engine 既可以包含 Host,也可以包含 Context,这是由具体的 Engine 实现确定的。

在 Servlet 编程中,一个 web 应用包含了多个 Servlet 来处理不同的连接请求,在 Tomcat 中,servlet 被封装成 Wrapper,与 Context 组合。

wrapper

Container

在 Tomcat 中,容器指的是一类组件,这类组件的作用就是处理接受自客户端的请求并且返回响应数据,尽管具体操作可能会委派到子组件完成。因此, Engine、Host、Context、Wrapper均属于容器。 Tomcat 使用 COntainer 表示容器, Container 可以添加并维护子容器。在 Tomcat 中,各个容器也不是聚合关系,即 Host 不会维护一个数组保存 COntext,而是通过父子容器的概念体现的。在 8.5.6版本之后,Service 持有一个 Engine 接口,在之前的版本 Service 持有一个Container 接口,更加通用:

container

Tomcat 的 Container 的另外一个最重要的功能就是后台处理。在很多情况下,我们需要 Container 自动执行一些异步处理。Container 的基础抽象类 (ContainerBase)确保组件启动的同时,异步启动后台处理,即调用 backgroundProcess() 方法。

上一篇下一篇

猜你喜欢

热点阅读