Tomcat配置文件server.xml详解
Server组件
1 | <Server port="8005" shutdown="SHUTDOWN"> |
这会让Tomcat启动一个server实例(即一个JVM),它监听在8005端口以接收shutdown命令
相关属性:
className: 实现此Server容器的全类名称,默认为org.apache.catalina.core.StandardServer
port: 接收shutdown指令的端口,默认仅允许通过本机访问,默认为8005
shutdown:发往此Server用于实现关闭tomcat实例的命令字符串,默认为SHUTDOWN
说明:管理员可以通过telnet连接8005端口后直接执行SHUTDOWN命令关闭Server容器(只允许本机执行)。
Connector组件
1 | <Connector port="8443" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" acceptCount="100" |
相关属性:
port:监听的端口,默认:0
address:指定连接器监听的地址,默认:0.0.0.0;
protocol:连接器使用的协议,默认:HTTP/1.1,定义AJP协议时通常为AJP/1.3
redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此端口
connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000,即1分钟
enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名,默认为true,一般不需要,可以设置为false
acceptCount:等待队列的最大长度,tomcat所有处理线程均处于繁忙状态时,新发来的请求将被放置于等待队列中
executor:指定配置的线程池名称
maxConnections:最大连接数,连接满时后续连接放入最大为acceptCount的队列中,对NIO和NIO2连接,默认:10000,对 APR/native,默认:8192
maxThreads:支持的最大并发连接数,默认:200, 如果指定了Executor此属性不生效
minSpareThreads:Connector创建线程池的最小活跃线程数,默认:10,如果指定了Executor此属性不生效
Executor 组件
1 | <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="300" minSpareThreads="25"/> |
相关属性:
name:线程池名称,要求唯一, 供Connector元素的executor属性使用
className:这个类必须实现org.apache.catalina.Executor接口
namePrefix:线程名称前缀
maxThreads:最大活跃线程数,默认:200
minSpareThreads:最小活跃线程数,默认:25
maxIdleTime:空闲线程关闭的等待最大时间,默认:60000ms,当前活跃线程大于minSpareThreads并且空闲时间大于maxIdleTime,该线程将会被回收。
maxQueueSize:线程池满情况下的请求排队大小,默认:Integer.MAX_VALUE
Engine组件
Engine是Servlet处理器的一个实例,默认为定义在server.xml中的Catalina。Engine需要defaultHost属性来为其定义一个接收所有发往非明确定义虚拟主机的请求的host组件
1 | <Engine name="Catalina" defaultHost="localhost"> |
相关属性:
defaultHost:设置默认虚拟主机,当引擎的连接器收到一个发往非明确定义虚拟主机的请求时,将发送到该虚拟主机
name:Engine组件的名称,用于日志和错误信息记录时区别不同的引擎
Engine容器中可以包含Realm、Host、Listener和Valve子容器。
Host组件:
Host组件用于定义虚拟主机,这些主机中至少要有一个跟defaultHost定义的主机名称同名
1 | <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"></Host> |
相关属性:
appBase:此Host的webapps目录,war文件的存放目录路径,可以使用基于$CATALINA_HOME的相对路径
autoDeploy:是否自动进行deploy,默认:true
unpackWars:在启用此webapps时是否对war格式的归档文件先进行展开,默认为true
Engine和Host组合示例:
1 | <Engine name="Catalina" defaultHost="localhost"> |
Context组件
Context在某些意义上类似于apache中的路径别名,一个Context定义用于标识tomcat实例中的一个Web应用程序;如下面的定义,在Tomcat6中,每一个context定义也可以使用一个单独的XML文件进行,其文件的目录为$CATALINA_HOME/conf//。可以用于Context中的XML元素有Loader,Manager,Realm,Resources和WatchedResource。
1 | <Context path="" docBase="/web/webapps"/> |
相关属性:
docBase:Web应用程序的存放位置,也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径,docBase的路径名不能与相应的Host中appBase中定义的路径名有包含关系,比如,如果appBase为deploy,而docBase绝不能为deploy-bbs类的名字;
path:相对于Web服务器根路径而言的URI;如果为空,则表示为此webapp的根路径,不能不配置该属性,如果context定义在一个单独的xml文件中,此属性不需要定义,有可能是别名
reloadable:/WEB-INF/classes/和/WEB-INF/lib/目录中class文件发生变化是否自动重新加载,默认:false
altDDName:web.xml部署描述符路径,默认:/WEB-INF/web.xml
failCtxIfServletStartFails,同Host中的failCtxIfServletStartFails, 只对当前Context有效,默认:false
logEffectiveWebXml:是否日志打印web.xml内容(web.xml由默认的web.xml和应用中的web.xml组成),默认:false
privileged:是否使用Tomcat提供的manager servlet
swallowOutput:System.out和System.err输出是否定向到web应用日志中,默认:false
Realm组件
一个Realm表示一个安全上下文,它是一个授权访问某个给定Context的用户列表和某用户所允许切换的角色相关定义的列表。因此,Realm就像是一个用户和组相关的数据库。定义Realm时惟一必须要提供的属性是classname,它是Realm的多个不同实现,用于表示此Realm认证的用户及角色等认证信息的存放位置。
1 | <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> |
相关属性:
JAASRealm:基于Java Authintication and Authorization Service实现用户认证
JDBCRealm:通过JDBC访问某关系型数据库表实现用户认证
JNDIRealm:基于JNDI使用目录服务实现认证信息的获取
MemoryRealm:查找tomcat-user.xml文件实现用户信息的获取
UserDatabaseRealm:基于UserDatabase文件(通常是tomcat-user.xml)实现用户认证,它实现是一个完全可更新和持久有效的MemoryRealm,因此能够跟标准的MemoryRealm兼容;它通过JNDI实现;
Valve组件
Valve类似于过滤器,它可以工作于Engine和Host、Context之间、Host和Context之间以及Context和Web应用程序的某资源之间。一个容器内可以建立多个Valve,而且Valve定义的次序也决定了它们生效的次序。Tomcat6中实现了多种不同的Valve:
相关属性:
AccessLogValve:访问日志Valve
ExtendedAccessValve:扩展功能的访问日志Valve
JDBCAccessLogValve:通过JDBC将访问日志信息发送到数据库中
RequestDumperValve:请求转储Valve
RemoteAddrValve:基于远程地址的访问控制
RemoteHostValve:基于远程主机名称的访问控制
SemaphoreValve:用于控制Tomcat主机上任何容器上的并发访问数量
JvmRouteBinderValve:在配置多个Tomcat为以Apache通过mod_proxy或mod_jk作为前端的集群架构中,当期望停止某节点时,可以通过此Valve将用记请求定向至备用节点;使用此Valve,必须使JvmRouteSessionIDBinderListener
ReplicationValve:专用于Tomcat集群架构中,可以在某个请求的session信息发生更改时触发session数据在各节点间进行复制
SingleSignOn:将两个或多个需要对用户进行认证webapp在认证用户时连接在一起,即一次认证即可访问所有连接在一起的webapp
ClusterSingleSingOn:对SingleSignOn的扩展,专用于Tomcat集群当中,需要结合ClusterSingleSignOnListener进行工作
RemoteHostValve和RemoteAddrValve可以分别用来实现基于主机名称和基于IP地址的访问控制,控制本身可以通过allow或deny来进行定义,如:
1 | <Context path="/probe" docBase="probe"> |
其中相关属性定义有:
className:相关的java实现的类名,相应于分别应该为org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve
allow:以逗号分开的允许访问的IP地址列表,支持正则表达式,因此,点号“.”用于IP地址时需要转义;仅定义allow项时,非明确allow的地址均被deny
deny: 以逗号分开的禁止访问的IP地址列表,支持正则表达式;使用方式同allow
GlobalNamingResources 应用于整个服务器的JNDI映射,此可以避免每个Web应用程序都需要在各自的web.xml创建,这在web应用程序以WAR的形式存在时尤为有用。它通常可以包含三个子元素:Environment,Resource、ResourceEnvRef
WatchedResource可以用于Context中监视指定的webapp程序文件的改变,并且能够在监视到文件内容发生改变时重新装载此文件
Listener用于创建和配置LifecycleListener对象,而LifecycleListener通常被开发人员用来创建和删除容器
Loader Java的动态装载功能是其语言功能强大表现之一,Servlet容器使用此功能在运行时动态装载servlet和它们所依赖的类。Loader可以用于Context中控制java类的加载
Manger对象用于实现HTTP会话管理的功能,Tomcat6中有5种Manger的实现
- StandardManager
Tomcat6的默认会话管理器,用于非集群环境中对单个处于运行状态的Tomcat实例会话进行管理。当Tomcat关闭时,这些会话相关的数据会被写入磁盘上的一个名叫SESSION.ser的文件,并在Tomcat下次启动时读取此文件。 - PersistentManager
当一个会话长时间处于空闲状态时会被写入到swap会话对象,这对于内存资源比较吃紧的应用环境来说比较有用。 - DeltaManager
用于Tomcat集群的会话管理器,它通过将改变了会话数据同步给集群中的其它节点实现会话复制。这种实现会将所有会话的改变同步给集群中的每一个节点,也是在集群环境中用得最多的一种实现方式。 - BackupManager
用于Tomcat集群的会话管理器,与DeltaManager不同的是,某节点会话的改变只会同步给集群中的另一个而非所有节点。 - SimpleTcpReplicationManager Tomcat4时用到的版本,过于老旧了。
14、Stores PersistentManager必须包含一个Store元素以指定将会话数据存储至何处。这通常有两种实现方式:FileStore和JDBCStore。
15、Resources 经常用于实现在Context中指定需要装载的但不在Tomcat本地磁盘上的应用资源,如Java类,HTML页面,JSP文件等。
16、Cluster 专用于配置Tomcat集群的元素,可用于Engine和Host容器中。在用于Engine容器中时,Engine中的所有Host均支持集群功能。在Cluster元素中,需要直接定义一个Manager元素,这个Manager元素有一个其值为org.apache.catalina.ha.session.DeltaManager或org.apache.catalina.ha.session.BackupManager的className属性。同时,Cluster中还需要分别定义一个Channel和ClusterListener元素。
16.1、Channel 用于Cluster中给集群中同一组中的节点定义通信“信道”。Channel中需要至少定义Membership、Receiver和Sender三个元素,此外还有一个可选元素Interceptor。
16.2、Membership 用于Channel中配置同一通信信道上节点集群组中的成员情况,即监控加入当前集群组中的节点并在各节点间传递心跳信息,而且可以在接收不到某成员的心跳信息时将其从集群节点中移除。Tomcat6中Membership的实现是org.apache.catalina.tribes.membership.McastService。
16.3、Sender 用于Channel中配置“复制信息”的发送器,实现发送需要同步给其它节点的数据至集群中的其它节点。发送器不需要属性的定义,但可以在其内部定义一个Transport元素。
16.4 Transport 用于Sender内部,配置数据如何发送至集群中的其它节点。Tomcat6有两种Transport的实现:
- PooledMultiSender 基于Java阻塞式IO,可以将一次将多个信息并发发送至其它节点,但一次只能传送给一个节点。
- PooledParallelSener 基于Java非阻塞式IO,即NIO,可以一次发送多个信息至一个或多个节点。
16.5 Receiver 用于Channel定义某节点如何从其它节点的Sender接收复制数据,Tomcat6中实现的接收方式有两种BioReceiver和NioReceiver。
Tomcat 各组件之间的关系
顶级组件:位于整个配置的顶层,server
容器类:可以包含其它组件的组件,service
连接器组件:连接用户请求至tomcat,connector
被嵌套类的组件:位于一个容器当中,不能包含其它组件
engine: 核心容器,catalina引擎,负责通过connector接收用户请求
host: 虚拟主机
context: 最内层的容器类组件,一个context代表一个web应用程序,配置context的主要目的,指定对应的webapp的根目录;还能为webapp指定额外的属性,如部署方式等
valve: 拦截请求并在将其转至对应的webapp之前进行某种处理操作,可以用于任何容器中
realm: 可以用于任何容器类的组件中,关联一个用户认证库,实现认证和授权户
webapp体系结构
/WEB-INF: 包含当前webapp的deploy描述符,如所有的servlets和JSP等动态文件的详细信息,会话超时时间和数据源等;因此,其也通常用于定义当前webapp特有的资源,通常web.xml和context.xml均放置于此目录
/WEB-INF/classes: 包含所有服务器端类及当前应用程序相关的其它第三方类等
/WEB-INF/lib: 包含JSP所用到的JAR文件,此webapp自有能够被打包为jar格式的类
Tomcat的HTTP连接器:
1、HTTP/1.1连接器,Tomcat6默认使用的连接器,即Coyote,它是Tomcat作为standalone模式工作时所用到的连接器,可直接响应来自用户浏览器的关于JSP、servlet和HTML的请求;此连接器是一个Java类,定义在server.xml当中
2、NIO HTTP/1.1连接器,它支持非阻塞式IO和Comnet,
3、C/C++开发的native APR HTTP/1.1连接器,在负载较大的场景中,可以提供非常好的性能
说明:APR即Apache Portable Runtime,它是一个能让开发者采用与平台无关的风格的方式来开发C/C++代码本地库,它能够很好的跨Windows, Linux和Unix平台工作。主要从三个方面优化了系统性能:
(1)使用sendfile()内核模式调用发送大的静态文件
(2)仅使用native code保持大量的连接
(3)使用能够加速SSL请求处理的OpenSSL本地代码
备注:启用APR连接器的条件:将连接器的protocol属性设定为org.apache.coyote.http11.Http11AprProtocol,APR的库文件已经在系统库文件的搜索路径内,必须额外编译安装apr
基于连接器提高Tomcat性能的方法:
- 设置tcpNoDelay属性值为 true
- 通过maxKeepAliveRequest属性调整允许keep-alive功能的请求的最大数目,值为1时表示禁用
- 调整socketBuffer属性的值以改变套接字缓冲的大小
- 将enableLookups设置为false以禁用DNS反解
- Tomcat是一个多线程的Servlet容器,使用线程池能对服务器性能带去很大影响;这主要通过maxThreads、maxSpareThreads和minSpareThreads来定义
- 通过JAVA_OPTS,如-Xms和-Xmx设定JVM相关的参数以定义其使用内存的能力
Tomcat Server处理一个HTTP请求的过程
- 用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得
- Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应
- 匹配Engine,Engine获得请求并匹配虚拟主机Host
- 匹配Context,如果匹配不到就把该请求交给路径名为””的Context去处理
- 匹配Servlet,path=”/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet
- 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost(),执行业务逻辑
- Context把执行完之后的HttpServletResponse对象返回给Host
- Host把HttpServletResponse对象返回给Engine
- Engine把HttpServletResponse对象返回Connector
- Connector把HttpServletResponse对象返回给客户Browser
Tomcat IO模型
BIO 阻塞式IO,采用传统的java IO进行操作,该模式下每个请求都会创建一个线程,适用于并发量小的场景
NIO 同步非阻塞,比传统BIO能更好的支持大并发,tomcat 8.0 后默认采用该模式
APR tomcat 以JNI形式调用http服务器的核心动态链接库来处理文件读取或网络传输操作,需要编译安装APR库
AIO 异步非阻塞,tomcat8.0后支持
配置方法:在tomcat conf 下找到server.xml
在
BIO: protocol =” org.apache.coyote.http11.Http11Protocol”
NIO: protocol =”org.apache.coyote.http11.Http11NioProtocol”
AIO: protocol =”org.apache.coyote.http11.Http11Nio2Protocol”
APR: protocol =”org.apache.coyote.http11.Http11AprProtocol”