优质博文:IT_BLOG_CN
一、Tomcat 顶层架构
Tomcat
中最顶层的容器是
Server
,代表着整个服务器,从上图中可以看出,一个
Server
可以包含至少一个
Service
,用于具体提供服务。
Service
主要包含两个部分:
Connector
和
Container
。从上图中可以看出
Tomcat
的心脏就是这两个组件,他们的作用如下:
【1】
Connector
用于处理连接相关的事情,并提供
Socket
与
Request
和
Response
相关的转化;
【2】
Container
用于封装和管理
Servlet
,以及具体处理
Request
请求;
一个
Tomcat
中只有一个
Server
,一个
Server
可以包含多个
Service
,一个
Service
只有一个
Container
,但是可以有多个
Connectors
,这是因为一个服务可以有多个连接,如同时提供
Http
和
Https
链接,也可以提供向相同协议不同端口的连接,示意图如下(
Engine
、
Host
、
Context
下边会说到):
多个
Connector
和一个
Container
就形成了一个
Service
,有了
Service
就可以对外提供服务了,但是
Service
还要一个生存的环境,必须要有人能够给她生命、掌握其生死大权,那就非
Server
莫属了!所以整个
Tomcat
的生命周期由
Server
控制。另外,上述的包含关系或者说是父子关系,都可以在
tomcat
的
conf
目录下的
server.xml
配置文件中看出。
二、简要解释下 server.xml 配置文件的信息
server.xml
是
Tomcat
中最重要的配置文件,
server.xml
的每个元素都对应了
Tomcat
中的一个组件;通过对
xml
文件中元素的配置,可以实现对
Tomcat
中各个组件的控制。
<?xml version="1.0" encoding="UTF-8"?><Serverport="8005"shutdown="SHUTDOWN"><ListenerclassName="org.apache.catalina.startup.VersionLoggerListener"/><ListenerSSLEngine="on"className="org.apache.catalina.core.AprLifecycleListener"/><ListenerclassName="org.apache.catalina.core.JasperListener"/><ListenerclassName="org.apache.catalina.core.JreMemoryLeakPreventionListener"/><ListenerclassName="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/><ListenerclassName="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/><GlobalNamingResources><Resourceauth="Container"description="User database that can be updated and saved"factory="org.apache.catalina.users.MemoryUserDatabaseFactory"name="UserDatabase"pathname="conf/tomcat-users.xml"type="org.apache.catalina.UserDatabase"/></GlobalNamingResources><Servicename="Catalina"><Connectorport="8080"protocol="HTTP/1.1"connectionTimeOut="20000"redirectPort="8443"/><Connectorport="8009"protocol="AJP/1.3"redirectPort="8443"/><EnginedefaultHost="localhost"name="Catalina"><RealmclassName="org.apache.catalina.realm.LockOutRealm"><RealmclassName="org.apache.catalina.realm.UserDatabaseRealm"resourceName="UserDatabase"/></Realm><HostappBase="webapps"autoDeploy="true"name="localhost"unpackWARs="true"><ValveclassName="org.apache.catalina.valves.AccessLogValve"directory="logs"pattern="%h %l %u %t "%r" %s %b"prefix="localhost_access_log."suffix=".txt"/><ContextdocBase="cas-server-webapp"path="/cas"reloadable="true"source="org.eclipse.jst.j2ee.server:cas-server-webapp"/><ContextdocBase="portal"path="/portal"reloadable="true"source="org.eclipse.jst.jee.server:portal"/></Host></Engine></Service></Server>
server.xml
的整体架构(简洁版):
<Server><Service><Connector/><Connector/><Engine><Host><Context/><!-- 现在常常使用自动部署,不推荐配置Context元素,Context小节有详细说明 --></Host></Engine></Service></Server>
【1】顶层元素:元素是整个配置文件的根元素,元素代表一个
Engine
元素以及一组与之相连的
Connector
元素。
【2】连接器: 代表了外部客户端发送请求到特定
Service
的接口;同时也是外部客户端从特定
Service
接收响应的接口。
【3】容器:容器的功能是处理
Connector
接收进来的请求,并产生对应的响应。
Engine
包含
Host
,
Host
包含
Context
。一个
Engine
组件可以处理
Service
中的所有请求,一个
Host
组件可以处理发向一个特定虚拟主机的所有请求,一个
Context
组件可以处理一个特定
Web
应用的所有请求。
三、Tomcat 都有哪些核心组件
【1】**
Server
:**
Server
元素在最顶层,代表整个
Tomcat
容器,因此他必须是
server.xml
中唯一一个最外层的元素。一个
Server
元素可以有一个或多个
Service
元素。
<Serverport="8005"shutdown="SHUTDOWN"></Server>
可以看到,最外层有一个 元素,
shutdown
属性表示关闭
Server
的指令;
port
属性表示
Server
接收
shutdown
指令的端口号,设置为
-1
可以禁掉该端口。Server 的主要任务,就是提供一个接口让客户端能够访问到这个 Service集合,同时维护它所包含的所有的 Service的生命周期,包含如何初始化,如何结束服务,如何找到客户端要访问的 Service。
【2】**
Service
:**在
Connector
和
Engine
外面包一层,把它们组合在一起,对外提供服务。一个
Service
可以包含多个
Connector
,但是只能包含一个
Engine
;其中
Connector
的作用是从客户端接收请求,
Engine
的作用是处理接收进来的请求。
<Serverport="8005"shutdown="SHUTDOWN"><Servicename="Catalina"></Service></Server>
如上图,
Server
中包含一个名称为
Catalina
的
Service
。实际上,
Tomcat
可以提供多个
Service
,不同的
Service
监听不同的端口。
【3】**
Connector
:**接收连接请求,创建
Request
和
Response
对象用于和请求端交换数据;然后分配线程让
Engine
来处理这个请求,并把产生的
Request
和
Response
对象传给
Engine
。通过配置
Connector
,可以控制请求 Service的协议及端口号。
<Serverport="8005"shutdown="SHUTDOWN"><Servicename="Catalina"><Connectorport="8080"protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"/><Connectorport="8009"protocol="AJP/1.3"redirectPort="8443"/></Service></Server>
通过配置第一个
Connector
,客户端可以通过
8080
端口号协议访问
Tomcat
。其中,
protocol
属性规定了请求的协议,
port
规定了请求的端口号,
redirectPort
表示当强制要求
https
而请求是 http时,重定向至端口号为
8443
的
Connector
,
connectionTimeout
表示连接的超时时间。
在这个例子中,
Tomcat
监听
Http
请求,使用的是
8080
端口,而不是正式的
80
端口;实际上,在正式的生产环境中,
Tomcat
也常常监听
8080
端口。而不是
80
端口。这是因为在生产环境中,很少讲
Tomcat
直接对外开放接收请求,而是在
Tomcat
和客户端之间加一层代理服务器(如
Nginx
),用于请求的转发、负载均衡、处理静态文件等;通过代理服务器访问
Tomcat
时,是在局域网中,因为一般仍使用
8080
端口。
第二个配置
Connector
,客户端可以通过
8009
端口使用
AJP
协议访问
Tomcat
。
AJP
协议负责和其他的
Http
服务器(如
Apache
)建立连接;在把
Tomcat
与其他服务器集成时,就需要用到这个连接器,之所以使用
Tomcat
和其他服务器集成,是因为
Tomcat
可以用作
Servlet/JSP
容器,但是对静态资源处理速度较慢,不如
Apache
和
IIS
等
HTTP
服务器;因此常常将
Tomcat
和
Apache
等集成,前者做
Servlet
容器,后者处理静态资源,而
AJP
协议便负责
Tomcat
与
Apache
的连接。
Tomcat
和
Apache
等集成的原理如下图:
【4】**
Engine
:**Engine 组件在
Service
组件有且只有一个;
Engine
是
Service
组件中的请求处理组件。
Engine
组件从一个或多个
Connector
中接收并处理,并将完成的响应返回给
Connector
,最终传递给客户端。前面说到,
Engine
、
Host
和
Context
都是容器,但是它们不是平行关系,而是父子关系:
Engine
包含
Host
,
Host
包含
Context
。
<Serverport="8005"shutdown="SHUTDOWN"><Servicename="Catalina"><Connectorport="8080"protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"/><Connectorport="8009"protocol="AJP/1.3"redirectPort="8443"/><Enginename="Catalina"defaultHost="localhost"></Engine></Service></Server>
其中
name
属性用于日志和错误信息,在整个
Server
中应该是唯一的。
defalutHost
属性指定了默认的
host
名称,当发往本机的请求指定的
host
名称不存在时,一律使用
defaultHost
指定的
host
进行处理;因此
defaulthost
的值,必须与
Engine
中的一个
Host
组件的
name
属性值匹配。
【5】**
Engine
和
Host
:**
Host
是
Engine
的子容器。
Engine
组件中可以内嵌
1
个或者多个
Host
组件,每个
Host
组件代表
Engine
中的一个虚拟主机。
Host
组件至少有一个,且其中一个的
name
必须与
Engine
组件中的
defaultHost
属性相匹配。
【6】**
Host
的作用:**
Host
虚拟主机的作用,是运行多个
Web
应用(一个
Context
代表一个
Web
应用),并负责安装、展开、启动、结束每个
Web
应用。
Host
组件代表的虚拟主机,对应服务器中一个网络名实体(如
www.test.com](https://links.jianshu.com/go?to=http%3A%2F%2Fwww.test.com)"或IP地址"116.25.25.25
);为了使用户可以通过网络名连接
Tomcat
服务器,这个名字应该在
DNS
服务器上注册。
客户端通常使用主机名来标识它们希望连接的服务器,该主机名也会包含在
HTTP
请求头中,
Tomcat
从
HTTP
头中提取出主机名,寻找名字匹配的主机。如果没有匹配,请求会发送至默认的主机。因此默认主机不需要再
DNS
服务器中注册网络名,因为任何与所有
Host
名称不匹配的请求,都会路由至默认主机。
【7】**
Host
的配置:**
name
属性指定虚拟主机的主机名,一个
Engine
有且只有一个
Host
组件的
name
属性和
Engine
组件的
defaultHost
属性相匹配;一般情况下,主机名需要是在
DNS
服务器中注册网络名,但是
Engine
指定的
defaultHost
不需要。
<Serverport="8005"shutdown="SHUTDOWN"><Servicename="Catalina"><Connectorport="8080"protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"/><Connectorport="8009"protocol="AJP/1.3"redirectPort="8443"/><Enginename="Catalina"defaultHost="localhost"><Hostname="localhost"appBase="webapps"unpackWARs="true"autoDeploy="true"></Host></Engine></Service></Server>
unpackWARs
指定了是否将代表
Web
应用的
WAR
文件解压;如果是
true
,通过解压后的文件结构运行该
Web
应用,如果是
false
,直接使用
WAR
文件运行
Web
应用。
【8】**
Context
:**
Context
元素代表在虚拟主机上运行的一个
Web
应用。在后文中,提到
Context
、应用或
Web
应用,他们都代指
Web
应用,每个
Web
应用基于
WAR
文件,或
WAR
文件解压后对应的目录(这里称为应用目录)
Context
是
Host
的子容器,每个
Host
都可以定义任意多的
Context
元素。元素的配置:
Context
元素最重要的属性是
docBase
和
path
,此外
reloadable
属性也比较常用。
docBase
指定了该
Web
应用使用
war
包路径,或应用目录。需要注意的是:在自动部署场景下(配置文件位于
xmlBase
中),
docBase
不在
appBase
目录中,才需要指定;如果
docBase
指定的
war
包或应用目录就在
appBase
中,则不需要指定。因为
Tomcat
会自动扫描
appBase
中的
war
包和应用目录,制定了反而造成问题。
path
指定了访问该
Web
应用上下文路径,当请求到来时,
Tomcat
根据
Web
应用的
path
属性与 URL匹配程度来选择
Web
应用处理相应请求。例如:
Web
应用
app1
的
path
属性是
/app1
,
Web
应用
app2
的
path
属性是"/app2",那么请求
/app1/index.html
会交由
app1
来处理;而请求
/app2/index.html
会交由
app2
来处理。如果一个
Context
元素的
path
属性为"",那么这个
Context
是虚拟主机的默认的
Web
应用;当请求的
uri
与所有的
path
都不匹配时,使用该默认
Web
应用来处理。
但是,需要注意的是,在自动部署场景(配置文件位于
xmlBase
中),不能指定path属性,
path
属性由配置的文件的文件名,
WAR
文件的文件名或应用目录的名称自动推导出来。如扫描
Web
应该时,发现
xmlBase
目录下的
app1.xml
,或
appBase
目录下的
app1.WAR
或
app1
应用目录,则该Web用于的
path
属性是
app1
。如果名称不是
app1
而是
ROOT
,则该Web应用时虚拟主机默认的
Web
应用,此时
path
属性推导为""。
reloadable
属性指示
tomcat
是否在运行时监控在
WEB-INF/classes
和
WEB-INF/lib
目录下
class
文件的改动。如果值为
true
,那么当
class
文件改动时,会重新
web
应用的重新加载。在开发环境下,
reloadable
设置为
ture
便于调试;但是在生产环境中设置为
true
会给服务器带来性能压力,因此
reloadable
参数的默认值为
false
。在该例子中,
docBase
位于
Host
的
appBase
目录之外;
path
属性没有指定,而是根据
app1.xml
自动推导为
app1
。
<ContextdocBase="D:\Program Files\app1.war"reloadable="true"></Context>
若是自动部署(即
autoDeploy="true"
),那么
server.xml
配置文件中没有
Context
元素的配置。这是因为
Tomcat
开启了自动部署,
Web
应用没有在
server.xml
中配置静态部署,而是由
Tomcat
通过特定的规则自动部署。
四、Web 的自动部署
要开启
Web
应用的自动部署,需要配置所在的虚拟主机;配置的方式就是在配置
Host
元素的
deployOnStartup
和
autoDeploy
属性。如果
deployOnStartup
和
autoDeploy
设置为
true
,则
tomcat
启动自动部署:当检测到新的
Web
应用或
Web
应用更新时,会触发应用的部署(或重新部署)。
二者的主要区别在于
【1】
deployeOnStartup
为
true
时,
Tomcat
在启动时检查
Web
应用,且检测到所有的
Web
应用都试做新应用;
【2】
autoDeploy
为
true
时,
Tomcat
在运行时定期检查新的
Web
应用或
Web
应用的更新;
通过配置
deployOnStartup
和
autoDeploy
可以开启虚拟主机自动部署
Web
应用;实际上,自动部署依赖于检查是否有新的或更改过的
Web
应用,而
Host
元素中的
appBase
和
xml
配置设置了检查
Web
应用更新的目录。
其中,
appBase
属性指定
Web
应用所在的目录,默认值是
webapps
,这是一个相对路径,代表
Tomcat
根目录下的
webapps
文件夹。
xmlBase
属性指定
Web
应用的
XML
配置文件所在的目录,默认值为
conf/<engine_name><engine_name>
,例如上面例子中,主机
localhost
的
xmlBase
的默认值是
$TOMCAT_HOME/conf/Catalina/localhost
。
五、appBase 和 docBase的区别
【1】**
appBase
:**这个目录下面的子目录将自动被部署为应用,且
war
文件将被自动解压缩并部署为应用,默认为
tomcat
下
webapps
目录。
【2】**
docBase
:**指定需要关联的项目自动解压并部署到
appBase
目录下。项目的名称由
path
属性决定。
先部署 需要注意,
docBase
所在的文件或者
war
包必须存在。否则项目启动找不到对应的目录。此时文件解压到
appBase
目录下,根据
path
属性,决定解压后的文件名。
若采用了
<Host name="localhost" appBase="webapp" autoDeploy="true">
配置,那么
appBase
目录下的应用目录将会再次部署。此时项目是部署了两遍。解决办法,设置
autoDeploy="false"
。
六、Tomcat 顶层架构小结
【1】
Tomcat
中只有一个
Server
,一个
Server
可以有多个
Service
,一个
Service
可以有多个
Connector
和一个
Container
;
【2】
Server
掌管着整个
Tomcat
的生死大权;
【3】
Service
是对外提供服务的;
【4】
Connector
用于接受请求并将请求封装成
Request
和
Response
来具体处理;
【5】
Container
用于封装和管理
Servlet
,以及具体处理
Request
请求;
知道了整个
Tomcat
顶层的分层架构和各个组件之间的关系以及作用,对于绝大多数的开发人员来说
Server
和
Service
对我们来说确实很远,而我们开发中绝大部分进行配置的内容是属于
Connector
和
Container
的,所以接下来介绍一下
Connector
和
Container
。
七、Connector 和 Container的微妙关系
由上述内容我们大致可以知道一个请求发送到
Tomcat
之后,首先经过
Service
然后会交给我们的
Connector
,
Connector
用于接收请求并将接收的请求封装为
Request
和
Response
来具体处理,
Request
和
Response
封装完之后再交由
Container
进行处理,
Container
处理完请求之后再返回给
Connector
,最后在由
Connector
通过
Socket
将处理的结果返回给客户端,这样整个请求的就处理完了!
Connector
最底层使用的是
Socket
来进行连接的,
Request
和
Response
是按照
HTTP
协议来封装的,所以
Connector
同时需要实现
TCP/IP
协议和
HTTP
协议。
Tomcat
既然处理请求,那么肯定需要先接收到这个请求,接收请求这个东西我们首先就需要看一下
Connector
。
八、Container 架构分析
Container
用于封装和管理
Servlet
,以及具体处理
Request
请求,在
Connector
内部包含了
4
个子容器,结构图如下:
4个子容器的作用分别是:
【1】
Engine
:引擎,用来管理多个站点,一个
Service
最多只能有一个
Engine
;
【2】
Host
:代表一个站点,也可以叫虚拟主机,通过配置
Host
就可以添加站点;
【3】
Context
:代表一个应用程序,对应着平时开发的一套程序,或者一个
WEB-INF
目录以及下面的
web.xml
文件;
【4】
Wrapper
:每一
Wrapper
封装着一个
Servlet
;
下面找一个
Tomcat
的文件目录对照一下,如下图所示:
Context
和
Host
的区别是
Context
表示一个应用,我们的
Tomcat
中默认的配置下
webapps
下的每一个文件夹目录都是一个
Context
,其中
ROOT
目录中存放着主应用,其他目录存放着子应用,而整个 webapps就是一个 Host站点。我们访问应用
Context
的时候,如果是
ROOT
下的则直接使用域名就可以访问,例如:www.ledouit.com,如果是
Host(webapps)
下的其他应用,则可以使用 www.ledouit.com/docs 进行访问,当然默认指定的根应用
ROOT
是可以进行设定的,只不过
Host
站点下默认的主营用是
ROOT
目录下的。
看到这里我们知道
Container
是什么,但是还是不知道
Container
是如何进行处理的以及处理完之后是如何将处理完的结果返回给
Connector
的。
十、Container 如何处理请求的
Container
处理请求是使用
Pipeline-Valve
管道来处理的!(
Valve
是阀门之意)
Pipeline-Valve
是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后将处理后的请求返回,再让下一个处理着继续处理。
但是!
Pipeline-Valve
使用的责任链模式和普通的责任链模式有些不同!区别主要有以下两点:
【1】每个
Pipeline
都有特定的
Valve
,而且是在管道的最后一个执行,这个
Valve
叫做
BaseValve
,
BaseValve
是不可删除的;
【2】在上层容器的管道的
BaseValve
中会调用下层容器的管道。
我们知道
Container
包含四个子容器,而这四个子容器对应的
BaseValve
分别在:
StandardEngineValve
、
StandardHostValve
、
StandardContextValve
、
StandardWrapperValve
。
Pipeline
的处理流程图如下:
【1】
Connector
在接收到请求后会首先调用最顶层容器的
Pipeline
来处理,这里的最顶层容器的
Pipeline
就是
EnginePipeline
(
Engine
的管道);
【2】在
Engine
的管道中依次会执行
EngineValve1
、
EngineValve2
等等,最后会执行
StandardEngineValve
,在
StandardEngineValve
中会调用
Host
管道,然后再依次执行
Host
的
HostValve1
、
HostValve2
等,最后在执行
StandardHostValve
,然后再依次调用
Context
的管道和
Wrapper
的管道,最后执行到
StandardWrapperValve
。
【3】当执行到
StandardWrapperValve
的时候,会在
StandardWrapperValve
中创建
FilterChain
,并调用其
doFilter
方法来处理请求,这个
FilterChain
包含着我们配置的与请求相匹配的
Filter
和
Servlet
,其
doFilter
方法会依次调用所有的
Filter
的
doFilter
方法和
Servlet
的
service
方法,这样请求就得到了处理!
【4】当所有的
Pipeline-Valve
都执行完之后,并且处理完了具体的请求,这个时候就可以将返回的结果交给
Connector
了,
Connector
在通过
Socket
的方式将结果返回给客户端。
十一、tomcat 容器是如何创建 servlet类实例?用到了什么原理?
当容器启动时,会读取在
webapps
目录下所有的
web
应用中的
web.xml
文件,然后对
xml
文件进行解析,并读取
servlet
注册信息。然后,将每个应用中注册的
servlet
类都进行加载,并通过反射的方式实例化。(有时候也是在第一次请求时实例化)在
servlet
注册时加上如果为正数,则在一开始就实例化,如果不写或为负数,则第一次请求实例化。
十二、共享 session处理
目前的处理方式有如下几种:
【1】使用
Tomcat
本身的
Session
复制功能。参考
http://ajita.iteye.com/blog/1715312
(
Session
复制的配置)方案的有点是配置简单,缺点是当集群数量较多时,
Session
复制的时间会比较长,影响响应的效率;
【2】使用第三方来存放共享
Session
:目前用的较多的是使用
memcached
来管理共享
Session
,借助于
memcached-sesson-manager
来进行
Tomcat
的
Session
管理。参考
http://ajita.iteye.com/blog/1716320
(使用
MSM
管理
Tomcat
集群
session
)
【3】使用黏性
session
的策略:对于会话要求不太强(不涉及到计费,失败了允许重新请求下等)的场合,同一个用户的
session
可以由
nginx
或者
apache
交给同一个
Tomcat
来处理,这就是所谓的
session sticky
策略,目前应用也比较多。参考:
http://ajita.iteye.com/blog/1848665(tomcat session sticky)Nginx
默认不包含
session sticky
模块,需要重新编译才行(
windows
下我也不知道怎么重新编译)优点是处理效率高多了,缺点是强会话要求的场合不合适。
十三、关于 Tomcat 的 session数目
这个可以直接从
Tomcat
的
web
管理界面去查看即可,或者借助于第三方工具
Lambda Probe
来查看,它相对于
Tomcat
自带的管理稍微多了点功能,但也不多 ;
十四、Tomcat 一个请求的完整过程
首先
DNS
解析机器,一般是
ng
服务器
ip
地址,然后
ng
根据
server
的配置,寻找路径为
yy/
的机器列表,
ip
和端口。最后 选择其中一台机器进行访问。下面为详细过程:
【1】请求被发送到本机端口
8080
,被在那里侦听的
Coyote HTTP/1.1 Connector
获得;
【2】
Connector
把该请求交给它所在的
Service
的
Engine
来处理,并等待来自
Engine
的回应;
【3】
Engine
获得请求
localhost/yy/index.jsp
,匹配它所拥有的所有虚拟主机
Host
;
【4】
Engine
匹配到名为 localhost 的 Host(即使匹配不到也把请求交给该 Host处理,因为该Host被定义为该 Engine的默认主机);
【5】
localhost Host
获得请求
/yy/index.jsp
,匹配它所拥有的所有
Context
;
【6】
Host
匹配到路径为
/yy
的
Context
(如果匹配不到就把该请求交给路径名为”“的
Context
去处理);
【7】
path=”/yy”
的
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
;
十五、Tomcat 工作模式
Tomcat
是一个
JSP/Servlet
容器。其作为
Servlet
容器,有三种工作模式:独立的
Servlet
容器、进程内的
Servlet
容器和进程外的
Servlet
容器。进入
Tomcat
的请求可以根据
Tomcat
的工作模式分为如下两类:
【1】
Tomcat
作为应用程序服务器:请求来自于前端的
web
服务器,这可能是
Apache
,
IIS
,
Nginx
等;
【2】
Tomcat
作为独立服务器:请求来自于
web
浏览器;
Tomcat
的工作一般分为三种:
【1】**
bio
:** 传统的
Java I/O
操作,同步且阻塞
I/O
,一个线程处理一个请求,并发量高时,线程数较多,浪费资源;(已经很少有人在使用)
【2】**
nio
:**
JDK1.4
开始支持,同步阻塞或同步非阻塞
IO
,可以通过少量的线程来处理大量的请求;(从
Tomcat 8
版本开始默认就是这种模式)
【3】**
apr
:** 以
JNI
的形式调用
Apache HTTP
服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高
Tomcat
对静态文件的处理性能;(企业中使用较多)
十六、如何对 Tomcat 进行优化
【1】关闭
Manager
管理页面;(默认已经关闭)
【2】关闭
host-mangent
管理页面;(默认已经关闭)
【3】对
Tomcat
日志进行分割;
【4】定义
Tomcat 404
错误返回的页面;
【5】对
JVM
进行优化;
【6】对
Tomcat
线程池进行优化;
十七、如何对 Tomcat 进行优化
【1】关闭
Manager
管理页面;(默认已经关闭)
【2】关闭
host-mangent
管理页面;(默认已经关闭)
【3】对
Tomcat
日志进行分割;
【4】定义
Tomcat 404
错误返回的页面;
【5】对
JVM
进行优化;
【6】对
Tomcat
线程池进行优化;
【7】更改
Tomcat
的工作的模式;
版权归原作者 程序猿进阶 所有, 如有侵权,请联系我们删除。