vlambda博客
学习文章列表

好家伙,我又被Tomcat干掉了!!!

前言


    刚入手JavaWeb项目时,还是通过手动配置Tomcat来部署项目,除此之外,还需要理清各个Jar包之间的关系,稍有不慎就会出现Jar包丢失或者应用版本冲突导致的服务启动异常,表示深爱并痛苦着.........。但是当入手Springboot之后,就再也没有去关注这些令人头大细节了,使得有更多的精力投入到业务逻辑的中去。


    可是就像Springboot一样,我们必须了解其中的工作原理、架构原理以及请求过程,这样在对项目进行优化时,我们能很快找到突破点。同时对于面试官来说,这些都是考点噢!!!!


那通过对Tomcat分析,具体有什么好处呢?

  1. 面试这关不用说吧?面试官题库满满的........

  2. 通过对Tomcat的结构和功能的理解和掌握,可以顺利排除Tomcat及应用程序出现的错误和异常。

  3. 可以优化其性能,甚至能扩展Tomcat的功能

  4. 通过对Tomcat源码的分析,学习一些好的编程习惯,学习一些解决问题的方法。

  5. 了解Tomcat的设计模式。



Tomcat 简介


Tomcat

    Tomcat 服务器是一个开源的轻量级Web应用服务器,在中小型系统和并发量小的场合下被普遍使用,是开发和调试Servlet、JSP 程序的首选。虽然Tomcat 部分是Apache 服务器的扩展,但它是独立运行的,所以当你运行Tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。


Tomcat的目录结构

好家伙,我又被Tomcat干掉了!!!


Tomcat 特点

  • 部署简单:只需将你的 WAR 放到 Tomcat 的 Webapp 目录下, Tomcat 会自动检测到这个文件, 并将其解压。

  • 安全管理:通过 Realm 可以方便地对访问某个应用的客户进行验证。

  • 易操作:基于 Tomcat 的开发其实主要是 JSP 和 Servlet 的开发,开发 JSP 和 Servlet 非常简单。

    好家伙,我又被Tomcat干掉了!!!

  • 集成方便:Tomcat 也可以与其他一些软件集成起来实现更多的功能。


Tomcat 架构原理



Tomcat 结构图

好家伙,我又被Tomcat干掉了!!!


Tomcat 组件

  • Server 服务器

    指的就是整个Tomcat 服务器,包含多组服务。负责管理和启动各个Service,同时监听 8005 端口发过来的shutdown命令,用于关闭整个容器

  • Service 服务

    Tomcat封装的、对外提供完整的、基于组件的 Web服务,包含Connector、Container 两个核心组件,以及多个功能组件。各个 Service 之间是独立的,但是共享同一JVM的资源

  • Connector 连接器

    Tomcat与外部世界的连接器,监听固定端口接收外部请求,传递给Container,并将Container 处理的结果返回给外部

    好家伙,我又被Tomcat干掉了!!!

           其实,Connecter组件通过对某个指定的端口进行侦听客户请求,接收浏览器的发过来的 TCP 连接请求,并创建一个Request和Response对象,用于和客户端交换数据,然后会产生一个线程来处理这个请求,并把产生的Request 和Response对象传给处理Engine(Container中的一部分),从Engine出获得响应并返回客户。 


    Connector 类别

    1. 侦听来自Browser的HTTP请求:HTTP/1.1 Connector在端口8080处侦听来自客户Browser的HTTP请求

    2. 侦听来自其他的WebServer请求:AJP/1.3 Connector在端口8009处侦听其他Web Server(其他的HTTP服务器)的Servlet/JSP请求


  • Container 容器

    好家伙,我又被Tomcat干掉了!!!


           Container其实是容器的父接口,该容器使用了责任链设计模式来进行设计,Container由Engine、Host、Context、Wrapper四个容器组件组成。而这四个组件之间是负责关系,或者说包含关系。一般一个Servlet class将会对应一个Wrapper,如果有多个Servlet,则定义多个Wrapper。如果有多个Wrapper,那就就需要定义一个更高的Container,如Context,而Context还可以定义在父容器Host中。虽然Host不是必须的,但是要运行war程序,就必须要Host,因为war包中必有web.xml文件,这个文件的解析就需要Host了,如果要有多个Host就要定义一个Top容器Engine了。而Engine没有父容器,一个 Engine 就代表一个完整的Servlet引擎。


    • Engine 容器 
      Engine 容器比较简单,它只定义了一些基本的关联关系

    • Host 容器 
      Host是Engine的子容器,一个Host在Engine中代表一个虚拟主机,这个虚拟主机的作用就是运行多个应用,它负责安装和展开这些应用,并且标识这个应用以便能够区分它们。它的子容器通常是 Context,它除了关联子容器外,还有就是保存一个主机应该有的信息。

    • Context 容器
      Context代表Servlet的Context,它具备了Servlet运行的基本环境,理论上只要有Context就能运行Servlet了。简单的Tomcat是可以没有Engine和Host的。Context最重要的功能就是管理它里面的Servlet实例,Servlet实例在Context中是以Wrapper出现的,还有一点就是 Context 如何才能找到正确的 Servlet 来执行它呢?Tomcat5 以前是通过一个 Mapper 类来管理的,Tomcat5 以后这个功能被移到了 request 中,在前面的时序图中就可以发现获取子容器都是通过 request 来分配的。

    • Wrapper 容器 
      Wrapper 代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。Wrapper 是最底层的容器,它没有子容器了,所以调用它的 addChild 将会报错。 
      Wrapper 的实现类是 StandardWrapper,StandardWrapper 还实现了拥有一个Servlet初始化信息的ServletConfig,由此看出 StandardWrapper 将直接和 Servlet 的各种信息打交道。

      好家伙,我又被Tomcat干掉了!!!


  • Jasper

    Tomcat 的 Jsp 解析引擎,用于将 Jsp 转换成 Java 文件,并编译成 class 文件。

  • Naming 

    命名服务,JNDI, Java 命名和目录接口,是一组在 Java 应用中访问命名和目录服务的 API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象,目录服务也是一种命名服务,对象不但有名称,还有属性。Tomcat 中可以使用 JNDI 定义数据源、配置信息,用于开发 与部署的分离。

  • Session 

    负责管理和创建 session,以及 Session 的持久化(可自定义),支持 session 的集群。

  • Loging 

    封装了 Java ClassLoader,用于 Container 加载类文件

  • Realm

    是Tomcat中为web应用程序提供访问认证和角色管理的机制

  • JMX

    Java SE 中定义技术规范,是一个为应用程序、设备、系统等植入管理功能的框架,通过 JMX 可以远程监控 Tomcat 的运行状态

好家伙,我又被Tomcat干掉了!!!

Tomcat 连接器&容器核心框架


    Tomcat 连接器框架——Coyote

    Tomcat 容器框架——Catalina


Tomcat的核心类图


好家伙,我又被Tomcat干掉了!!!


Tomcat 请求流程




Tomcat 处理一次HTTP请求的过程说明

  1. 用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。 

  2. Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。 

  3. Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。 

  4. Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理)。 

  5. path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。 

  6. 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序。 

  7. Context把执行完之后的HttpServletResponse对象返回给Host。 

  8. Host把HttpServletResponse对象返回给Engine。 

  9. Engine把HttpServletResponse对象返回Connector。 

  10. Connector把HttpServletResponse对象返回给客户Browser。


Tomcat HTTP请求流程

参考资料:

[1]http://www.tomcat.org.cn/

[2]https://blog.csdn.net/u014231646/article/details/79482195

[3]https://blog.csdn.net/jsj13263690918/article/details/80368757

[4]https://www.cnblogs.com/hggen/p/6264475.html

[5]https://blog.csdn.net/xiliunian/article/details/107540584

[6]https://blog.51cto.com/gaohl/1918133

[7]https://zhuanlan.zhihu.com/p/248426114

[8]https://www.jianshu.com/p/c94dc6c64ec5

内容来源于网络,如有侵权请联系删除,在此对于此行为表示抱歉。