title: Tomcat 组件简介
date: 2020/05/06 17:19
本节内容
先简单介绍一下 Tomcat 中的各种组件,要不你后面听不懂
├── Server 组件
├── Service 组件
│ │── 连接器
│ └── 容器
│ │── Engine
│ │── Host
│ │── Context
│ └── Wrapper
│ └── Pipline
│ │── Valve
│ └── ValveContext
├── 类加载器
└── Lifecycle
概念简介
conf/server.xml
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
根据Tomcat自身的分类,上面这些元素可以分成四种:
- 顶级元素 - 即Server和Service,前者是本配置文件的根节点,后者则起到了一个包裹内部组件的作用。换句话说,它们都属于“单纯的、不具有具体职能的配置节点”。
- 容器 - Tomcat内真正负责处理请求并返回结果的组件。
- Connector - Connector(接头)是一个特殊的组件,如果说整个Tomcat是一堵墙,它就是安装在墙上的插座。外部的客户端通过这些插座来跟Tomcat建立联系。
- 嵌套组件 - 这是一些嵌套在各种容器内部的组件,有些可以放在任意一层容器内,例如Listener;有些只能放在固定的位置,例如GlobalNamingResources。
一、顶层元素
1.1 Server (服务器)组件
一个Tomcat只有一个 Server.xml,即一个Tomcat实例只有一个Server。
它不是一个容器,它只是单纯地扮演着一个包裹的角色。
它代表 Tomcat 实例本身。
元素属性
<Server port="8005" shutdown="SHUTDOWN" />
Server可配置的属性很少。根据上面摘录的默认配置,Server会侦听localhost的TCP端口8005,当该端口接收到字符串"SHUTDOWN"时,即执行关闭Tomcat操作。
嵌套组件
Server有两种特有的组件,一个是GlobalNamingResources(全局命名资源),一个是Service(服务)。
除此之外,还可以有Listener(监听器)这种可以作用于不同层次容器的组件。Server默认配置了六种Listener。配置在Server这一层的Listener对所有容器起作用。
总结
它代表整个 Tomcat 实例,因此它还有一个作用,就是监听 SHUTDOWN 请求。
它是一个顶层组件,用于包裹它下面的多个 Service 组件。
1.2 Service (服务)组件
一个Service就是一个完整的服务,负责将若干个Connector和一个Engine(引擎)包裹在一起。除此之外,Service还可以配置一个Executor(共享线程池)用于管理所有Connector的线程数量。
嵌套组件
如图所示,Service有Executor、Connector和Engine三种组件。其中,每个Connector负责侦听一个TCP端口,接收相应的请求,并转发给绑定的Engine处理。Engine处理完后,通过Connector把结果返回给客户端。在配置了Executor的情况下,所有Connector的线程受Executor统一管理。
总结
它的作用是将多个连接器与容器实例联系起来,使得不同协议的请求可以使用同一个容器来处理。
二、容器
Engine
Engine是Service的请求处理引擎,负责处理所有Connector发过来的请求,并将内部处理完毕的结果返回给Connector。它是最外层的容器。
元素属性
<Engine name="Catalina" defaultHost="localhost" />
Engine.name - 引擎的名称
Engine.defaultHost - 默认采用哪一个子容器Host来处理请求
总结
Engine 的作用是可以采用一个连接器接收请求并映射到不同的域名中
Host
一个Host就是一个虚拟主机,对应一个或多个域名。
元素属性
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true" />
Host.name - 主机名称(域名)
默认配置定义了一个名为 localhost 的主机。至少要有一个Host的名称与Engine的defaultHost一致。
除了域名外,Host可以通过子节点alias来配置别名。别名的作用与域名一致。例如:
<Host name="www.a.com" ...>
...
<Alias>a.com</Alias>
<Alias>blog.a.com</Alias>
<Alias>c.com</Alias>
...
</Host>
其作用机制如下图所示:
Host.appBase - 虚拟主机的根目录
Host.unpackWARs - 放到 webapps 目录下的 WAR-file 是否应该被解压
Host.autoDeploy - 是否自动部署放到 webapps 目录下的应用
Context
Context代表Host下面的一个虚拟目录。
元素属性
默认是不配置的
<Context path="mzdbxqh" docBase="D:/mzdbxqh" debug="0" reloadable="true" crossContext="true"/>
Context.docBase - 应用程序的路径或者是WAR文件存放的路径
Context.path - 此web应用程序的上下文路径
Context.reloadable - 是否支持热部署
如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes目录的变化,并通过类加载器重新加载class文件,以实现在不重启tomcat的情况下重新部署。
Context.crossContext - 不同context是否共享session
三、其他
Connector组件
开头说过,Connector就是墙上的插座,负责侦听一个具体的TCP端口,并通过该端口处理Engine与客户端之间的交互。默认配置定义了两个 Connector:
<!--HTTP/1.1:处理 HTTP 请求,使得 Tomcat 成为了一个 HTTP 服务器。客户端可以通过 Connector 向服务器发送 HTTP 请求,接收服务器端的 HTTP 响应信息。-->
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<!--connectionTimeOut 属性定义了这个 connector 在链接获得同意之后,获得请求 URI line(请求信息)响应的最大等待时间毫秒数。默认为20秒。redirect 属性会把 SSL 请求重定向到 TCP 的8443端口。-->
<!--AJP/1.3:Apache JServ Protocol connector 处理 Tomcat 服务器与 Apache HTTP 服务器之间的交互。-->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
Valve
Valve的中文含义是阀门,可以简单地理解为Tomcat的拦截器。它负责在请求发送到应用之前拦截HTTP请求,可以定义在任何容器中。默认配置中定义了一个AccessLogValve,负责拦截HTTP请求,并写入到日志文件中。
Listener 组件
Listener即监听器,负责监听服务器端的行为。此处需要了解的监听器有两个:
<!--作用于 Jasper JSP 引擎,该引擎负责对更新后的 JSP 页面进行重编译。-->
<Listener className="org.apache.catalina.core.JasperListener" />
<!--作用于全局资源,保证 JNDI 对资源的可达性,比如数据库。-->
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
四、Tomcat处理Http请求的过程
请求地址为:http://my.oschina.net/mzdbxqh
- 请求通过DNS发送到指定主机的80端口,被负责侦听80端口的HTTP/1.1 Connector拦截
- Connector把请求转发给所在的Service的Engine,并等待Engine的回应
- Engine获得请求my.oschina.net/mzdbxqh,匹配它所拥有的所有虚拟主机Host
- Engine匹配到名为my.oschina.net的Host,如果匹配不到就交给defaultHost
- 匹配的Host获得请求/mzdbxqh,匹配它所拥有的所有Context
- Host匹配到path为mzdbxqh的Context,如果匹配不到就尝试匹配Path为""的Context,如果还匹配不到就尝试到appBase参数对应的目录下找mzdbxqh文件夹
- 匹配的Context获得请求/,匹配web.xml中配置的Servlet,如果匹配不到就尝试匹配Welcome-file-list
- Context匹配到url-pattern为"/"的servlet,对应于org.springframework.web.servlet.DispatcherServlet
- SpringMVC处理请求,返回HttpServletResponse
- Context把HttpServletResponse对象返回给Host
- Host把HttpServletResponse对象返回给Engine
- Engine把HttpServletResponse对象返回给Connector
- Connector把HttpServletResponse对象返回给客户端