编辑
2023-11-03
Tomcat源码学习
00
请注意,本文编写于 554 天前,最后修改于 554 天前,其中某些信息可能已经过时。

目录

总体架构
Tomcat支持的IO模型
Tomcat 支持的 I/O 模型有:
Tomcat 支持的应用层协议有:
连接器组件图

总体架构

Tomcat 要实现 2 个核心功能:

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

因此 Tomcat 设计了两个核心组件连接器(Connector)和容器(Container)来分别做这两件事情。连接器负责对外交流,容器负责内部处理。

Tomcat支持的IO模型

Tomcat 支持的 I/O 模型有:

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

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

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

Tomcat 支持的应用层协议有:

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

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

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

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

image.png

从图上你可以看到,最顶层是 Server,这里的 Server 指的就是一个 Tomcat 实例。一个 Server 中有一个或者多个 Service,一个 Service 中有多个连接器和一个容器。连接器与容器之间通过标准的 ServletRequest 和 ServletResponse 通信。

连接器对 Servlet 容器屏蔽了协议及 I/O 模型等的区别,无论是 HTTP 还是 AJP,在容器中获取到的都是一个标准的 ServletRequest 对象。

我们可以把连接器的功能需求进一步细化,比如:

  • 监听网络端口。

  • 接受网络连接请求。

  • 读取请求网络字节流。

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

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

  • 调用 Servlet 容器,得到 ServletResponse。

  • 将 ServletResponse 转成 Tomcat Response 对象。

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

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

需求列清楚后,我们要考虑的下一个问题是,连接器应该有哪些子模块?优秀的模块化设计应该考虑高内聚、低耦合。

  • 高内聚是指相关度比较高的功能要尽可能集中,不要分散。

  • 低耦合是指两个相关的模块要尽可能减少依赖的部分和降低依赖的程度,不要让两个模块产生强依赖。

需要实现的功能

  • 网络通信。

  • 应用层协议解析。

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

因此 Tomcat 的设计者设计了 3 个组件来实现这 3 个功能,分别是 EndPoint、Processor 和 Adapter。

由于 I/O 模型和应用层协议可以自由组合,比如 NIO + HTTP 或者 NIO2 + AJP。Tomcat 的设计者将网络通信和应用层协议解析放在一起考虑,设计了一个叫 ProtocolHandler 的接口来封装这两种变化点。各种协议和通信模型的组合有相应的具体实现类。比如:Http11NioProtocol 和 AjpNioProtocol。

连接器模块用三个核心组件:Endpoint、Processor 和 Adapter 来分别做三件事情,其中 Endpoint 和 Processor 放在一起抽象成了 ProtocolHandler 组件,它们的关系如下图所示。 image.png

image.png

连接器组件图

image.png

本文作者:yowayimono

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!