Tomcat 架构概述

Tomcat 是一个 Web 应用服务器,它是对 HTTP 和 Servlet 规范的实现,简单来说它做了这几件事:处理 HTTP 协议、执行 Servlet 和处理网络 I/O。

这里以 6.0.53 版本为例(实现了 HTTP/1.1、Servlet2.5),研究其基本结构。 关于源码版本,我使用的是 tomcat6,因为 7 为了重构有太多的抽象,看着实在费劲,6 代码虽有冗余但读起来很直观,并且低版本也不影响理解 Tomcat 的核心流程。

体系结构

从 server.xml 中就能够看出 Tomcat 各组件的层次结构,具体结构图如下:


 Tomcat 架构

•Server:代表整个容器,它可能包含一个或多个 Service 和全局 JNDI 资源;

•Service:包含一个或多个 Connector,这些连接器与一个 Engine 相关联;

•Engine:表示请求处理流水线(pipeline),它接收所有连接器的请求,并将响应交给适当的连接器返回给客户端;

 •Host:网络名称(域名)与 Tomcat 服务器的关联,默认主机名 localhost,一个 Engine 可包含多个 Host;

•Connector:处理与客户端的通信,网络 I/O;

 •Context:表示一个 Web 应用程序,一个 Host 包含多个上下文。

学习群64弍46衣3凌9,资料群69似64陆0吧3

 服务器模型

服务器模型(或 I/O 模型),描述的是 TCP 连接的处理方式,以及 Socket 读写时线程的状态。

Java 里常用的是 BIO 和 NIO,分别对应同步阻塞和同步非阻塞两种模型,Tomcat 中的 Connector 组件就是对这两种的封装实现。

BIO - 阻塞式

Tomcat 实现了一个一连接一线程的简单服务器模型,内部采用线程池做了优化,设计如下:


Tomcat BIO 模型

•当 Acceptor 接收到一个 TCP 连接时,线程池分配一个线程进行处理;

•线程调用 read() 方法读取 Socket 输入流中的字节,此时线程阻塞(Block),直到收到客户端发送的数据;

•收到数据后,进行解码、业务处理、编码,最后把响应发送到客户端,关闭连接。

由此可以看出,合理的分配线程池大小可以一定程度上提高系统的并发能力。

NIO - 非阻塞

BIO 的缺点在于不管当前连接有没有数据传输,它始终阻塞占用线程池内的一个线程,而 NIO 的处理方式是若通道无数据可读取,此时线程不阻塞直接返回,可用于处理其他连接,提高了线程利用率。那怎么知道什么时候处理数据的读写呢?当通道可读或可写时,内核会通知用户程序进行处理。

 NIO 的编程比较复杂,常用的是 Reactor 模式,它描述了一个利用多路复用 I/O,基于事件驱动的服务器处理模型,(这里) 基于 Doug Lea 的 Scalable IO in Java 对 Reactor 进行了实现。

Tomcat 的设计略有不同,其设计如下:


Tomcat NIO 模型

•Acceptor 以阻塞模式接收 TCP 连接,然后将连接注册到 Poller 上;

•Poller 以非阻塞模式处理 SSL 握手和 HTTP 请求头的读取;

•BlockPoller 模拟阻塞处理 HTTP 请求体的读取和发送响应。 值得注意的是,两类 Poller 都只是负责事件的通知,I/O 操作都是由线程池中的线程完成。

那么,ServerSocketChannel 为什么阻塞?为什么要模拟阻塞处理请求体和 Servlet 响应?

相关的讨论可参考:

 •Why Tomcat's Non-Blocking Connector is using a blocking socket?

•Getting my head around NIO 'simulated' blocking (trying to)

Servlet API 的实现 Servlet 规范描述了容器如何加载和运行 Servlet,如和将请求映射到用户配置的 Servlet, 如何处理请求和响应等相关问题。

Tomcat 主要实现了以下 API:

•ServletConfig :Servlet 名字和初始化参数;

•ServletContext :定义了 Web 应用程序,Servlet 运行的上下文;

•ServletRequest :封装客户端请求;

 •ServletResponse :封装服务端响应;

•FilterChain :请求过滤调用链;

•FilterConfig :过滤配置对象;

•RequestDispatcher :转发请求,将请求转发给 JSP 或另一个 Servlet 处理。 其他如 Servlet、Filter、GenericServlet、HttpServlet 接口或类则由用户程序来实现,更多详细的介绍请参考规范内容。

 小结

Tomcat 架构看着挺简单但做起来难,难的就是把复杂的问题抽象化、简单化,体现到代码上就是如何设计和抽象出类并且优雅的组织在一起,它作为一个流行的中间件,其内部代码的实现以及优化手段,也是值得我们去研究和模仿的。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Tomcat 是一个 Web 应用服务器,它是对 HTTP 和 Servlet 规范的实现,简单来说它做了这几件事...
    wskwbog阅读 1,168评论 0赞 6
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 43,028评论 11赞 349
  • 0 系列目录# WEB请求处理 WEB请求处理一:浏览器请求发起处理 WEB请求处理二:Nginx请求反向代理 本...
    七寸知架构阅读 14,299评论 22赞 189
  • 概述 Tomcat是一个JSP/Servlet容器。其作为Servlet容器,有三种工作模式:独立的Servlet...
    jiangmo阅读 2,353评论 0赞 13
  • 01概念与认知 关于世间上的事物,每个人的字典里都有着不同的解释。每个人对同一样东西都有着不同的概念理解,也就是认...
    瑜卤考拉阅读 954评论 0赞 0

友情链接更多精彩内容