Tomcat源码解析之架构设计

背景

Tomcat作为JavaWeb领域的Web容器,大多数Java应用的Web容器都使用了Tomcat,为了对平时开发的Web系统有更深入的理解,出于好奇心对我们的Web系统是如何跑在Tomcat上的,前段时间仔细研究整理了Tomcat的源码以及之前看过的技术点进行分享,大家都知道Servlet规范是Java领域中为服务端编程制定的规范,对于我们开发者只是关注了Servlet规范中提供的编程组件(ServletContextListener,Filter,Servlet等),但是规范中还有一些我们经常使用的接口(ServletContext,ServletRequest,ServletResponse,FilterChain)等都是由Tomcat去实现的,并且我们开发者实现的编程组件只是被Tomcat去回调而已,所以看Tomcat源码有助于我们更好的理解Servlet规范及系统如何在容器中运行的(一些开源的MVC框架Struts2,Webx,SpringMVC本质上就是这),整理相关学习资料,以便日后回顾(Tomcat版本:10.0.10)

Tomcat和Catalina是什么关系

Tomcat的前身为Catalina,Catalina是一个轻量级的Servlet容器

Tomcat的前身为Catalina,Catalina又是一个轻量级的Servlet容器。Tomcat从4.x开始除了作为支持Servlet容器外,额外加了很多的功能,不如:jsp、el、naming等等,所以Tomcat不仅仅是Catalina。

什么是Servlet

所谓Servlet,其实就是Sun为了让Java能实现动态可交互的网页,从而进入Web编程领域而制定的一套标准

一个Servlet主要做下面三件事情:

  • 创建并填充Request对象,包括:URL、参数、method、请求头信息、请求体信息等
  • 创建Response对象
  • 执行业务逻辑,将结果通过Response的输出流出到客户端

Servlet没有main方法,所以:如果要执行,则需要在一个容器里面才能执行,这个容器就是为了支持Servlet的功能而存在,Tomcat其实就是一个Servlet容器的实现。

Tomcat整体架构

从组件角度看

  • Server: 表示服务器,它提供了一种优雅的方式来启动和停止整个系统,不必单独启停连接器和容器;它是Tomcat构成的顶级构成元素,所有一切均包含在Server中;

  • Service: 表示服务,Server可以运行多个服务。Server的实现类StandardServer可以包含一个到多个Services

  • Container: 表示容器,可以看做Servlet容器;引擎(Engine)、主机(Host)、上下文(Context)和Wraper均继承自Container接口,所以它们都是容器。

  • Engine -- 引擎

  • Host -- 主机

  • Context -- 上下文

  • Wrapper -- 包装器

  • Connector : 表示连接器, 它将Service和Container连接起来,首先它需要注册到一个Service,它的作用就是把来自客户端的请求转发到Container(容器),这就是它为什么称作连接器, 它支持的协议如下:

  • 支持AJP协议

  • 支持Http协议

  • 支持Https协议

  • Service内部还有各种支撑组件,下面简单罗列一下这些组件

  • Manager -- 管理器,用于管理会话Session

  • Logger -- 日志器,用于管理日志

  • Loader -- 加载器,和类加载有关,只会开放给Context所使用

  • Pipeline -- 管道组件,配合Valve实现过滤器功能

  • Valve -- 阀门组件,配合Pipeline实现过滤器功能

  • Realm -- 认证授权组件

从一个完整请求的角度来看

来自客户的请求为:http://localhost:8080/test/index.jsp请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector,然后

  • Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应
  • Engine获得请求localhost:8080/test/index.jsp,匹配它所在虚拟机主机Host
  • localhost Host获得请求/test/index.jsp,匹配它所拥有虚拟主机Context
  • Context匹配URL PARRTERN为*.jsp的servlet,对应于JspServlet类,构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
  • Context把HttpServletResponse对象返回给Engine
  • Engine把HttpServletResponse对象返回给Connector
  • Connector把HttpServletResponse对象返回给浏览器

从源码的设计角度看

  • **Jsper模块:**这个模块负责jsp页面的解析、jsp属性的验证,同时负责jsp页面动态转换为java代码并编译成class文件。在源码中,org.apache.jasper的源码都属于这个子模块
  • Servlet和Jsp模块: 这个子模块的源代码属于javax.servlet包及其子包,如我们非常熟悉的javax.servlet.Servlet接口、javax.servet.http.HttpServlet类及javax.servlet.jsp.HttpJspPage就位于这个子模块中;
  • Catalina模块: 这个模块是需要阅读和学习的重点,包含了所有org.apache.catalina开头的源码,该模块规范了Tomcat的总体架构,定义了Server、Service、Host、Connector、Context、Session以及Cluster等关键组件的实现,同时也规范了Catalina的启动及停止事件的执行流程。
  • **Connector模块:**上面三个子模块实现的是tomcat应用服务器,该模块是Web服务的实现,它接收用户的请求,并把用户请求包装成标准的Http请求(包含协议名称、请求头Head,请求方法Get 或Post).
  • **Resource 模块:**这个模块包括一些资源文件,如Server.xml及Web.xml配置文件。这个子模块不包含java源码,但是是Tomcat编译运行所必须的

展望

后面将从源码视角对Tomcat如何启动初始化和如何接收请求具体展开分析讲解

相关推荐
XINGTECODE41 分钟前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
天天扭码1 小时前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶1 小时前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺1 小时前
Spring Boot框架Starter组件整理
java·spring boot·后端
余生H1 小时前
transformer.js(三):底层架构及性能优化指南
javascript·深度学习·架构·transformer
凡人的AI工具箱1 小时前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
先天牛马圣体1 小时前
如何提升大型AI模型的智能水平
后端
java亮小白19971 小时前
Spring循环依赖如何解决的?
java·后端·spring
2301_811274312 小时前
大数据基于Spring Boot的化妆品推荐系统的设计与实现
大数据·spring boot·后端
运维&陈同学2 小时前
【zookeeper01】消息队列与微服务之zookeeper工作原理
运维·分布式·微服务·zookeeper·云原生·架构·消息队列