Tomcat服务器系统架构学习笔记

目录

1.Tomcat 总体架构

1.1 Tomcat 核心功能

1.2 Tomcat核心组件

1.3 Service 组件

2.Tomcat 支持的 I/O 模型和应用层

2.1 I/O 模型

2.2 应用层协议

3.连接器(Connector)

3.1连接器具体功能

3.2 EndPoint

3.3 Processor

3.4 ProtocolHandler 组件

3.5 Adapter 组件

3.6 连接器总结

4.容器(Container)

4.1容器的层次结构

4.2 定位 Servlet

4.3 请求的链式调用

4.4 容器总结


Tomcat服务器的功能为:处理 Socket 连接,负责网络字节流与 Request 和 Response 对象的转化,加载和管理 Servlet,以及具体处理 Request 请求。因此服务器包含连接器(Connector)--对外交流和容器(Container)--内部处理两大核心组件。本文旨在记录自己学习过程,把自己的过程分享出来,如有不合理的地方欢迎各位大佬提出指教~~~


1.Tomcat 总体架构

1.1 Tomcat 核心功能

  • 处理 Socket 连接,负责网络字节流与 Request 和 Response 对象的转化
  • 加载和管理 Servlet,以及具体处理 Request 请求

1.2 Tomcat核心组件

  • 连接器(Connector)--对外交流
  • 容器(Container)--内部处理

1.3 Service 组件

单独的连接器或者容器都不能对外提供服务,需要把它们组装起来才能工作,组装后这个整体叫作 Service 组件。Service 本身没有做什么重要的事情,只是在连接器和容器外面多包了一层,把它们组装在一起。Tomcat 内可能有多个 Service,这样的设计也是出于灵活性的考虑。通过在 Tomcat 中配置多个 Service,可以实现通过不同的端口号来访问同一台机器上部署的不同应用。

 一个 Server 中有一个或者多个 Service,一个 Service 中有多个连接器和一个容器。连接器与容器之间通过标准的 ServletRequest 和 ServletResponse 通信。

2.Tomcat 支持的 I/O 模型和应用层

2.1 I/O 模型

  • NIO:非阻塞 I/O,采用 Java NIO 类库实现。

  • NIO2:异步 I/O,采用 JDK 7 最新的 NIO2 类库实现。

  • APR:采用 Apache 可移植运行库实现,是 C/C++ 编写的本地库。

2.2 应用层协议

  • HTTP/1.1:这是大部分 Web 应用采用的访问协议。

  • AJP:用于和 Web 服务器集成(如 Apache)。

  • HTTP/2:HTTP 2.0 大幅度的提升了 Web 性能。

3.连接器(Connector)

3.1连接器具体功能

  • 监听网络端口。

  • 接受网络连接请求。

  • 读取请求网络字节流。

  • 根据具体应用层协议(HTTP/AJP)解析字节流,生成统一的 Tomcat Request 对象。

  • 将 Tomcat Request 对象转成标准的 ServletRequest。

  • 调用 Servlet 容器,得到 ServletResponse。

  • 将 ServletResponse 转成 Tomcat Response 对象。

  • 将 Tomcat Response 转成网络字节流。

  • 将响应字节流写回给浏览器。

以上集合成以下三个功能

  • 网络通信。

  • 应用层协议解析。

  • Tomcat Request/Response 与 ServletRequest/ServletResponse 的转化。

根据功能设计以下三个对应的子模块,设计要求:高内聚、低耦合

  • EndPoint,EndPoint 负责提供字节流给 Processor
  • Processor,Processor 负责提供 Tomcat Request 对象给 Adapter
  • Adapter,Adapter 负责提供 ServletRequest 对象给容器

高内聚是指相关度比较高的功能要尽可能集中,不要分散。低耦合是指两个相关的模块要尽可能减少依赖的部分和降低依赖的程度,不要让两个模块产生强依赖。

3.2 EndPoint

EndPoint 是通信端点,即通信监听的接口,是具体的 Socket 接收和发送处理器,是对传输层的抽象,因此 EndPoint 是用来实现 TCP/IP 协议的。

EndPoint 是一个接口,对应的抽象实现类是 AbstractEndpoint,而 AbstractEndpoint 的具体子类,比如在 NioEndpoint 和 Nio2Endpoint 中,有两个重要的子组件:Acceptor 和 SocketProcessor。

  • Acceptor 用于监听 Socket 连接请求
  • SocketProcessor 用于处理接收到的 Socket 请求,它实现 Runnable 接口,在 Run 方法里调用协议处理组件 Processor 进行处理

3.3 Processor

Processor 接收来自 EndPoint 的 Socket,用来实现 HTTP 协议,读取字节流解析成 Tomcat Request 和 Response 对象,下一步通过 Adapter 将其提交到容器处理,Processor 是对应用层协议的抽象。

从图中我们看到,EndPoint 接收到 Socket 连接后,生成一个 SocketProcessor 任务提交到线程池去处理,SocketProcessor 的 Run 方法会调用 Processor 组件去解析应用层协议,Processor 通过解析生成 Request 对象后,会调用 Adapter 的 Service 方法。

3.4 ProtocolHandler 组件

ProtocolHandler 组件由EndPoint 和 Processor组成,网络通信和应用层协议解析放在一起考虑,设计了一个叫 ProtocolHandler 的接口来封装这两种变化点。

3.5 Adapter 组件

Adapter 组件的作用在于将 Tomcat Request 转成 ServletRequest,便于容器的调用。

3.6 连接器总结

连接器负责对外交流,容器负责内部处理。连接器用 ProtocolHandler 接口来封装通信协议和 I/O 模型的差异,ProtocolHandler 内部又分为 EndPoint 和 Processor 模块,EndPoint 负责底层 Socket 通信,Proccesor 负责应用层协议解析。连接器通过适配器 Adapter 调用容器。

4.容器(Container)

容器,顾名思义就是用来装载东西的器具,在 Tomcat 里,容器就是用来装载 Servlet 的。

4.1容器的层次结构

Tomcat 通过一种分层的架构,使得 Servlet 容器具有很好的灵活性,Tomcat 设计了 4 种容器,这些容器不是平行关系,而是父子关系。关系如下图:

  • Engine(一个)
  • Host(多个)
  • Context(多个)
  • Wrapper(多个)

Engine 表示引擎,用来管理多个虚拟站点,一个 Service 最多只能有一个 Engine。

Host 代表的是一个虚拟主机,或者说一个站点,可以给 Tomcat 配置多个虚拟主机地址,而一个虚拟主机下可以部署多个 Web 应用程序。

Context 表示一个 Web 应用程序。

Wrapper 表示一个 Servlet,一个 Web 应用程序中可能会有多个 Servlet。

4.2 定位 Servlet

方法:通过Mapper组件完成对Servlet的定位。当一个请求到来时,Mapper 组件通过解析请求 URL 里的域名和路径,再到自己保存的 Map 里去查找,就能定位到一个 Servlet。请你注意,一个请求 URL 最后只会定位到一个 Wrapper 容器,也就是一个 Servlet。

举个形象的例子

  • 网购系统例子

假如有一个网购系统,有面向网站管理人员的后台管理系统,还有面向终端客户的在线购物系统。这两个系统跑在同一个 Tomcat 上,为了隔离它们的访问域名,配置了两个虚拟域名:manage.shopping.comuser.shopping.com,网站管理人员通过manage.shopping.com域名访问 Tomcat 去管理用户和商品,而用户管理和商品管理是两个单独的 Web 应用。终端客户通过user.shopping.com域名去搜索商品和下订单,搜索功能和订单管理也是两个独立的 Web 应用。

针对这样的部署,Tomcat 会创建一个 Service 组件和一个 Engine 容器组件,在 Engine 容器下创建两个 Host 子容器,在每个 Host 容器下创建两个 Context 子容器。由于一个 Web 应用通常有多个 Servlet,Tomcat 还会在每个 Context 容器里创建多个 Wrapper 子容器。每个容器都有对应的访问路径,以下图形象化。

 

假如有用户访问一个 URL,比如图中的http://user.shopping.com:8080/order/buy,Tomcat 如何将这个 URL 定位到一个 Servlet 呢?

首先,根据协议和端口号选定 Service 和 Engine。

我们知道 Tomcat 的每个连接器都监听不同的端口,比如 Tomcat 默认的 HTTP 连接器监听 8080 端口、默认的 AJP 连接器监听 8009 端口。上面例子中的 URL 访问的是 8080 端口,因此这个请求会被 HTTP 连接器接收,而一个连接器是属于一个 Service 组件的,这样 Service 组件就确定了。我们还知道一个 Service 组件里除了有多个连接器,还有一个容器组件,具体来说就是一个 Engine 容器,因此 Service 确定了也就意味着 Engine 也确定了。

然后,根据域名选定 Host。

Service 和 Engine 确定后,Mapper 组件通过 URL 中的域名去查找相应的 Host 容器,比如例子中的 URL 访问的域名是user.shopping.com,因此 Mapper 会找到 Host2 这个容器。

之后,根据 URL 路径找到 Context 组件。

Host 确定以后,Mapper 根据 URL 的路径来匹配相应的 Web 应用的路径,比如例子中访问的是 /order,因此找到了 Context4 这个 Context 容器。

最后,根据 URL 路径找到 Wrapper(Servlet)。

Context 确定后,Mapper 再根据 web.xml 中配置的 Servlet 映射路径来找到具体的 Wrapper 和 Servlet。

4.3 请求的链式调用

Pipeline-Valve 是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后将再调用下一个处理者继续处理。

4.4 容器总结

容器负责内部处理,连接器处理 Socket 通信和应用层协议的解析,得到 Servlet 请求;而容器则负责处理 Servlet 请求。容器是分层级的,Tomcat 容器用mapper组件根据请求定位 Servlet,最后调用Servlet。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值