面试官:Tomcat是如何处理Http请求的?

服务器
Servlet是JavaEE规范的一种,主要是为了扩展Java作为Web服务的功能,统一接口。

[[376467]]

 Servlet技术是我们java后端工程师必须掌握的,这里我们可以把java web技术路线可以大致归纳为如下过程:

 

因为tomcat实现了Servlet规范,所以我们得掌握什么是Servlet?什么是Servlet规范?

什么是Servlet呢?

Servlet是JavaEE规范的一种,主要是为了扩展Java作为Web服务的功能,统一接口。由其他内部厂商如tomcat,jetty内部实现web的功能。如一个http请求到来:容器将请求封装为servlet中的HttpServletRequest对象,调用init(),service()等方法输出response,由容器包装为httpresponse返回给客户端的过程。

 

什么是Servlet规范?

  • 从 Jar 包上来说,Servlet 规范就是两个 Jar 文件。servlet-api.jar 和 jsp-api.jar,Jsp 也是一种 Servlet。
  • 从package上来说,就是 javax.servlet 和 javax.servlet.http 两个包。
  • 从接口来说,就是规范了 Servlet 接口、Filter 接口、Listener 接口、ServletRequest 接口、ServletResponse 接口等。类图如下:

 

为什么我们将tomcat称为Web容器或者Servlet容器 ?

我们用一张图来表示他们之间的关系:

 

简单的理解:启动一个ServerSocket,监听8080端口。Servlet容器用来装我们开发的Servlet。

tomcat架构介绍

tomcat架构图

 

架构图与tomcat中conf下面的server.xml中内容对比:

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <Server port="8005" shutdown="SHUTDOWN"
  3.   <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> 
  4.   <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> 
  5.   <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> 
  6.   <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> 
  7.   <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> 
  8.   <GlobalNamingResources> 
  9.     <Resource name="UserDatabase" auth="Container" 
  10.               type="org.apache.catalina.UserDatabase" 
  11.               description="User database that can be updated and saved" 
  12.               factory="org.apache.catalina.users.MemoryUserDatabaseFactory" 
  13.               pathname="conf/tomcat-users.xml" /> 
  14.   </GlobalNamingResources> 
  15.   <Service name="Catalina"
  16.     <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 
  17.     <Engine name="Catalina" defaultHost="localhost"
  18.       <Realm className="org.apache.catalina.realm.LockOutRealm"
  19.         <Realm className="org.apache.catalina.realm.UserDatabaseRealm" 
  20.                resourceName="UserDatabase"/> 
  21.       </Realm> 
  22.       <Host name="localhost"  appBase="webapps" 
  23.             unpackWARs="true" autoDeploy="true"
  24.         <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 
  25.                prefix="localhost_access_log" suffix=".txt" 
  26.                pattern="%h %l %u %t &quot;%r&quot; %s %b" /> 
  27.         <Context docBase="F:/workspace/my-web-maven/target" path="/" reloadable="true" />  
  28.         <Context docBase="F:/workspace/my-web-maven/target" path="/tian" reloadable="true" />  
  29.   </Host> 
  30.     </Engine> 
  31.   </Service> 
  32. </Server> 

架构图和server.xml内容对比,server.xml就是架构图的xml版本,由此可以猜测我们java代码中也应该有与之对应的类。

比如说:Listener类、Service类、Host类、Engine类等,这个后面再具体分析,这里只是猜测一下我们java代码中的实现。

看过前面Mybatis源码分析文章的同学,这里也应该能猜到,这个server.xml配置文件解析方式以及如何存放这些配置信息。

tomcat启动时是通过读取server.xml配置文件的参数,加载每个对应的组件,同时该文件中配置了tomcat的相关可调控参数,实际项目中对tomcat的优化工作大部分都是这个配置文件里的参数调整。

tomcat组件介绍

server

关于server和tomcat的关系,可以理解为我们说的启动一个tomcat就是启动一个server。

作为Tomcat最外层的核心组件,Server组件的作用主要有以下几个。

  • 提供了监听器机制,用于在Tomcat整个生命周期中对不同事件进行处理;
  • 提供了Tomcat容器全局的命名资源实现;
  • 监听某个端口以接收SHUTDOWN命令;

service

Service 表示一个或多个 Connector 的集合,这些 Connector 共享同一个 Container 来处理其请求。在同一个 Tomcat 实例内可以包含任意多个 Service 实例,它们彼此独立

ConnectorConnector用于接受请求并将请求封装成Request和Response,然后交给Container进行处理,Container处理完之后在交给Connector返回给客户端。

Container

Container用于封装和管理Servlet,以及具体处理Request请求;包含4大请求处理组件:引擎(engine)、虚拟主机、上下文(context)组件。Container是容器的父接口,用于封装和管理Servlet,以及具体处理Request请求,该容器的设计用的是典型的责任链的设计模式,它由四个自容器组件构成,分别是Engine、Host、Context、Wrapper。这四个组件是负责关系,存在包含关系。只包含一个引擎。

Engine

表示整个 Servlet 引擎。在 Tomcat 中, Engine 为最高层级的容器对象。尽管 Engine 不是直接处理请求的容器,却是获取目标容器的入口。引擎表示可运行的Catalina的servlet引擎实例,并且包含了servlet容器的核心功能。在一个服务中只能有一个引擎。同时,作为一个真正的容器,Engine元素之下可以包含一个或多个虚拟主机Host。

Host

代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点。Host容器是Engine容器的子容器,上面也说到Host是受Engine容器管理的,就是指一个虚拟主机,比如我们在访问具体jsp页面URL中localhost就是一个虚拟主机,其作用是运行多个应用,并对这些应用进行管理,其子容器是Context,而且一个主机还保存了主机的相关信息。

Context

Context 作为一类容器,用于表示 Servletcontext ,在 Servlet 规范中,一个 Servletcontext 即表示一个独立的 Web 应用。代表一个应用程序,对应着平时研发的一套程序,或者WEB-INF目录以及下面的web.xml文件 。

WapperWapper 作为一类容器,用于表示 Web 应用中定义的 Servlet,每一个Wrapper封装这一个Servlet。

组件关系

 

tomcat两个核心组件

Connector:主要负责处理Socket连接,以及Request与Response的转化。

Container:包括Engine、Host、Context和Wrapper,主要负责内部的处理以及Servlet的管理

tomcat处理Http请求流程

上面说完了tomcat整体架构,下面我们来说说,假设来我们在浏览器上输入

http://localhost:8080/my-web-mave/index.jsp

在tomcat中是如何处理这个请求流程的:

  1. 我们的请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得。
  2. Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应 。
  3. Engine获得请求localhost/my-web-maven/index.jsp,匹配它所拥有的所有虚拟主机Host ,我们的虚拟主机在server.xml中默认配置的就是localhost。
  4. Engine匹配到name=localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)。
  5. localhost Host获得请求/my-web-maven/index.jsp,匹配它所拥有的所有Context。
  6. Host匹配到路径为/my-web-maven的Context(如果匹配不到就把该请求交给路径名为”"的Context去处理)。
  7. path=”/my-web-maven”的Context获得请求/index.jsp,在它的mapping table中寻找对应的servlet 。
  8. Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类。
  9. 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法 。
  10. Context把执行完了之后的HttpServletResponse对象返回给Host 。
  11. Host把HttpServletResponse对象返回给Engine 。
  12. Engine把HttpServletResponse对象返回给Connector 。
  13. Connector把HttpServletResponse对象返回给客户browser 。流程图:有些模糊。

本文转载自微信公众号「Java后端技术全栈」,可以通过以下二维码关注。转载本文请联系Java后端技术全栈公众号。

 

责任编辑:武晓燕 来源: Java后端技术全栈
相关推荐

2023-09-19 22:41:30

控制器HTTP

2022-08-08 13:45:12

Redis面试Hash

2021-05-12 08:20:53

开发

2021-05-27 05:37:10

HTTP请求头浏览器

2023-10-04 07:35:03

2022-04-08 08:26:03

JavaHTTP请求

2022-04-01 12:38:32

cookie代码面试

2021-04-30 20:25:20

Spring MVCJava代码

2024-02-04 10:08:34

2015-08-13 10:29:12

面试面试官

2023-02-08 07:04:20

死锁面试官单元

2022-01-18 09:02:45

请求前端代码

2021-05-13 07:58:05

HTTPSHTTP安全

2020-04-20 08:35:48

HTTP HTTPS网络协议

2023-07-31 08:26:09

2023-12-19 09:24:22

LinuxBIOSUEFI

2010-08-12 16:28:35

面试官

2019-04-29 14:59:41

Tomcat系统架构

2021-09-27 07:11:18

MySQLACID特性

2023-03-06 08:37:58

JavaNIO
点赞
收藏

51CTO技术栈公众号