Tomcat的配置管理篇1-服务器配置(server.xml、context.xml等)

897 阅读2分钟

欢迎大家关注 github.com/hsfxuebao ,希望对大家有所帮助,要是觉得可以的话麻烦给点一下Star哈

Tomcat服务器的配置主要集中于$CATALINA_HOME/conf下的catalina.policy、catalina.properties、context.xml、server.xml、tomcat-users.xml、web.xml文件。本篇我们重点说明catalina.properties、server.xml、context.xml这三个配置文件。

1. catalina.properties

该文件主要用于Catalina容器启动阶段的配置,如服务器类加载器路径等,配置属性如表:

属性描述
package.access该属性指定了一个包路径列表(以“,”分割),当Wb应用加载类时,会判断加载的包路径是否包含在该列表中。如包含,则会进一步检查该包路径是否拥有RuntimePermission许可。如果没有,将提示加载异
常。
package.definition该属性与package,access类似,不同的是前者用于限制是否可以访问某个包下的类,而后者用于限制是否可以在某个包下定义类。相比较而言,后者要更严格
common.loaderTomcat公共类加载器加载JAR包路径列表(类加载器),默认值为$CATALINA_BASE/lib$CATALINA_HOME/lib下的所有JAR包
server.loaderTomcat应用服务器类加载器加载JAR包路径列表,默认值为空,此时Tomcat直接使用公共类加载器作为应用服务器类加载器
shared.loaderTomcat Web应用父类加载器加载JAR包路径列表,默认值为空,此时Tomcat直接使用公共类加载器作为应用服务器类加载器
tomcat.util.scan.StandardJarScanFilter.jars-ToSkip这是当Tomeat使用JarScanner扫描JAR包时(主要是TLD文件和web-fragment.xml文件扫描)可以跳过的JAR包列表。合理配置该属性,可以提升Tomcat启动性能。该属性作为所有Web应用的默认配置,如果希望每个Web应用单独定义排除列表,可以在Context一级添加配置
tomcat.util.scan.StandardJarScanFilter.jars-ToScan这是当Tomcat{使用JarScanner扫描JAR包时需要扫描的JAR包列表。该属性主要用于覆盖jarsToSkip,当jarsToSkip指定了一个相对较广泛的表达式时,可以通过该属性将少数几个符合表达式但需要扫描的JAR包含进来
tomcat.util.buf.StringCache.byte.enabled是否为ByteChunk启用String缓存,用于ByteChunk的toString处理

2.server.xml

server.xml是Tomcat)应用服务器的核心配置文件,它包括Tomcat Servlet容器(Catalina)的所有组件的配置,用于创建Tomcat Servlet容器。由于Catalina中每各组件支持的属性非常多,我们在本章只介绍一部分关键属性的配置方式。

本节按照Catalina各组件层级逐一进行讲解,如果对Catalina中各组件的概念不是很了解,可 参见Tomcat架构篇1-Tomcat总体设计以及核心组件

2.1 Server

server.xml的根元素为Server,用于创建一个Server实例,默认使用的实现类为org,apache.catalina.core.StandardServer。默认配置如下:

<Server port="8005"shutdown="SHUTDOWN">
</Server>
  • port: Tomcat监听的关闭服务器的端口
  • shutdown: 关闭服务器的指令字符串

Serveri可以内嵌的子元素为:Service、GlobalNamingResources和Listener。 其中,Listener用于为Server添加生命周期监听器。默认的5个监听器如下:

<!-用于以日志形式输出服务器、操作系统、VM的版本信息-->
<Listener className="org.apache.catalina.startup.VersionLoggerListener"></Listener>

<!-用于加载(服务器启动)和销毁(服务器停止)APR。如果找不到APR库,则会输出日志,并不影响Tomcat.启动-->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"></Listener>

<!-用于避兔JRE内存泄漏问题-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"></Listener>

<!- 用户加载(服务器启动)和销毁(服务器停止)全局命名服务->
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>

<!-用于在Context停止时重建Executor池中的线程,以避免ThreadLoca1相关的内存泄漏-->
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"></Listener>

GlobalNamingResources定义了全局的命名服务。

<!--Global JNDI resources
    Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
    <!--Editable user database that can also be used by
        UserDatabaseRealm to authenticate users
    -->
    <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"></Resource>
</GlobalNamingResources>

2.2 Service

该元素用于创建Service实例,默认使用org.apache.catalina.core.StandardService。

默认情况下,Tomcat仅指定了Service的名称,值为“Catalina”。Service可以内嵌的元素为:Listener、Executor、Connector、Engine。同Server一样,Listener用于为Service添加生命周期监听器,默认情况下,Tomcat并未添加任何Service一级的监听器配置。Executor用于配置Service共享线程池。Connector用于配置Service包含的链接器。Engine用于配置Servicer中链接器对应的Servlet容器引擎。除Listener外,其他元素的配置可参见本节后续讲解。

注意:实际上,我们很少会修改Server和Service的属性。更多是对子元素如Executor、Connector、Host、Context等进行配置优化。

一个Server服务器,可以包含多个Service服务。

2.3 Executor

默认情况下,Service并未添加共享线程池配置。如果我们想添加一个线程池,可以在<Service>下添加如下配置:

<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="200"
minSpareThreads="100"
maxIdleTime="60000"
maxQueuesize="Integer.MAX_VALUE"
prestartminSpareThreads="false"
threadPriority="5"
className="org.apache.catalina.core.StandardThreadExecutor"></Executor>

属性含义如下:

属性含义
name线程池名称,用于Connectori中指定。
namePrefix所创建的每个线程的名称前缀,一个单独的线程名称为namePrefix+threadNumber
maxThreads池中最大线程数。
minSpareThreads活跃线程数,也就是核心池线程数,这些线程不会被销毁,会一直存在。
maxIdleTime线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为6000(1分钟),单位毫秒。
maxQueueSize在被执行前最大线程排队数目,默认为lt的最大值,也就是广义的无限。除非特殊情况,这个值不需要史改,否则会有请求不会被处理的情况发生。
prestartminSpareThreads启动线程池时是否启动minSpareThreads部分线程。默认值为false,即不启动
threadPriority线程池中线程优先级,默认值为5,值从1到10。
className线程池实现类,未指定情况下,默认实现类为org.apache.catalina.core.StandardThreadExecutor.如果想使用自定义线程池首先需要实现org.apache.catalina.Executor接口。

如果不配置共享线程池,那么Catalina各组件在用到线程池时会独立创建。

2.4 Connector

Connector用于创建链接器实例。默认情况下,server.xml配置了两个链接器,一个支持HTTP协议,一个支持AJP协议。因此大多数情况下,我们并不需要新增链接器配置,但是需要针对已有链接器进行优化。

链接器的配置主要分为协议和I/O两个方面。

  • 协议层面,如protocol用于指定具体的处理协议,以及HTTP Connector的compression)属性和compressableMimeType)属性用于配置HTTP/1.1 GZIP压缩,以节省服务器带宽,提升系统性能。

  • I/O层面,如maxConnections、acceptCount、maxThreads等用于控制服务器的请求链接数。

一个简单的链接器配置如下:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"></Connector>

其中属性说明如下

  • port: 端口号,Connector用于创建服务端Socket并进行监听,以等待客户端请求链接。同一个IP地址的同一个端口号,操作系统只允许存在一个服务端应用监听。如果该属性设置为0,Tomcat将随机选择一个可用的端口号给当前Connector使用。

  • protocol:当前Connector支持的访问协议。默认为HTTP/1.l,并采用自动切换机制选择一个基于JAVA NIO的链接器或者基于本地APR的链接器。如果Windows的PATH或者类Unix系统的LD_LIBRARY_PATH环境变量包含一个Tomcat本地库,将使用本地的APR链接器。如果没有对应本地库,将使用基于Java的非阻塞式链接器。

    注意,APR链接器与Java链接器相比有不同的HTTPS设置。如果不希望采用上述自动切换机制,而是明确指定协议,可以使用以下值。

    HTTP协议:

    org.apache.coyote.httpl1.Http11NioProtocol,非阻塞式Java NIO链接器。
    org.apache.coyote.httpll.Httpl1NioProtocol,非阻塞式Java NIO2链接器。
    org.apache.coyote.httpll.Http11AprProtocol,APR链接器。
    

    AJP协议:

    org.apache..coyote.ajp.AjpNioProtocol,非阻塞式Java NIO链接器。
    org.apache..coyote.ajp.AjpNio2 Protocol,非阻塞式Java NIO2链接器。
    org.apache.coyote..ajp.AjpAprProtocol,.APR链接器。
    
  • connectionTimeout:Connector接收链接后的等待超时时间,单位为毫秒。-1表示不超时,在server.xml文件中配置的值为20000。除非disableUploadTimeouti设置为false,此属性也用于控制读取请求体。

  • redirectPort:如果当前Connector支持non-SSL请求,并且接收到一个请求,符合<security-constraint>约束,需要SSL传输,Catalina自动将请求重定向到此处指定的端口。

除此之外,对于链接器,我们经常需要增加一些高级属性以满足生产环境的需要

  • 线程池(executor): 增加线程池配置以提升服务器请求处理并发数。此时,可以通过属性executor指定共享线程池的名称,也可以通过maxThreads、minSpareThreads等属性配置链接器内部线程池。

  • 最大接收链接数(acceptCount):与maxConnections属性不同,acceptCount用于控制Socket中排队链接的最大个数,当Socket排队链接到达acceptCounth时,服务器将拒绝新的链接请求。maxConnections用于控制服务端线程池可处理的最大链接数,当链接数到达该数值后,请求将处于等待状态。因此服务器可以接收的请求总数为maxConnections + acceptCount。

    maxConnections默认值为线程池的maxThreads。因为如果大于该值,即便服务器创建新的请求处理任务,该任务在线程池中也只能排队等待。如果小于该值,线程池中会存在空闲线程,如此会浪费系统资源。

  • URI编码(URIEncoding): 用于指定解码URI的字符编码,在xx%解码之后。默认编码为ISO-8859-1。由于在实际开发中经常采用UTF-8编码,因此建议将该值设置为UTF-8,以减少开发过程中额外的编解码工作。

  • GZIP压缩:Connector通过4个属性控制HTTP请求的GZIP压缩功能。首先,将属性compressioni设置为on开启GZP压缩。其次,通过属性compressableMimeType指定哪些类型的响应可以压缩,如text/html、text/xml、text/plain。最后,通过compressionMinSize指定响应内容大小的限制,当响应内容大于该值时,才会进行GZP压缩。最后,noCompressionUserAgents,用于指定一个正则表达式,对于user-agent头信息匹配的HTTP请求将不进行压缩。采用GZIP压缩可以大大减少HTTP请求的传输数据量,提升系统访问性能,节省网络带宽,因此建议在生产环境中增加GZP压缩相关配置。

  • enableLookups: 该属性设置为true,在调用request.getRemoteHost()方法时将执行DNS查询以返回远程客户端的实际主机名称。设置为false,将跳过该查询直接返回P地址以提高性能。

综上,一个较为完整的Connector配置如下:

<Connector port="8080"
    executor="sharedThreadPool"
    enableLookups="false"
    redirectPort="8443"
    acceptCount="100"
    connectionTimeout="20000"
    URIEncoding="UTF-8"
    compression="on"
    compressionMinSize="2048"
    noCompressionUserAgents="gozilla,traviata"
    compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"/>

注意,上述配置必须确保已经添加了一个名为“sharedThreadPool'”的共享线程池。

2.5 Engine

Engine作为Servlet引擎的顶级元素,它支持以下嵌入元素:Cluster、Listener、Realm、Valve和Host。

其中,Cluster用于集群配置。Listener用于添加Engine 一级的生命周期监听器,默认情况下未配置任何监听器。Realm 主要用户安全。Valve用于添加一个org.apache.catalina.Valve实现,拦截Engine一级的请求处理(除非需要跨Host、跨Web应用进行拦截处理,否则不要轻易在Engine元素下配置Valve)。Host用于配置Tomcat虚拟主机组件。Engine配置如下:

<Engine name="Catalina"defaultHost="localhost">
..
</Engine>
  • name: 用于指定Engine的名称,默认为Catalina。该名称会影响一部分Tomcat使用的存储路径,如临时文件。

  • defaultHost:默认使用的虚拟主机的名称,当客户端请求指向的主机无效时,将交由默认虚拟主机处理。默认为localhost。

除此之外,在生产环境中我们还经常用到的一个属性就是jvmRoute,它主要用于在负载均衡场景下启用粘性会话。jvmRoute在整个集群所有Tomcat服务器中必须唯一,而且它会附加到生成的会话ID。通过此种方式,前端代理服务器可以将来自某个特定会话的请求定向到同一个Tomcat实例。

2.6 Host

Host元素用于配置一个虚拟主机,它支持以下嵌入元素:Alias、Cluster、Listener、Valve、Realm和Context。其中,Cluster、Listener、Valve、Realm与Engine相同,不同的是作用域为Host。Alis用于为Host配置别名,这样我们除了通过Host名称访问当前主机外,还可以通过别名访问。Context用于配置Host下运行的Web应用。

如果在Engine下配置Ream,那么此配置将在当前Engine下的所有Host中共享。同样,在Host配置Realm,则在当前Host下的所有Context中共享。当然,Context中配置的Realm优先级最高,其次为Host,最后是Engine。 Host的配置如下:

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
</Host>

默认情况下,Engine下只包含了一个虚拟机,其配置如下。

  • name:当前Host通用的网络名称,必须与DNS服务器上的注册信息一致。因为Tomcat内部会将Host名称转换为小写,所以不能通过大小写来区分Host名称。Engine中包含的Host必须存在一个名称与Enginet的defaultHost设置一致。

  • appBase:当前Host的应用基础目录,在当前Host上部署的Web应用均在该目录下。可以是一个绝对路径,也可以是一个相对路径(相对于$CATALINA_BASE)。默认为webapps

  • unpackWARs:设置为true,Host在启动时会将appBase目录下的WAR包解压为目录。设置为false,Host将直接从WAR文件中启动Web应用。Host的appBase目录外的WAR文件不会解压缩。

  • autoDeploy: 该标识用于控制Tomcat是否在运行时定期检测新增或者存在更新的Web应用。如果为true,Tomcat将定期检测appBase和xmlBase目录,部署新发现的Web应用或者Context描述文件。存在更新的Web应用或者Context描述文件将触发Web应用的重新加载。默认为true。

    Tomcat经常使用Engine和Host的名称来确定服务目录,如Web应用的临时工作目录(基于默认配置):$CATALINA_BASE/work/Catalina/localhost,Web应用context.xml的副本目录:$CATALINA_BASE/Catalina/localhost

通过为Host添加别名,我们可以实现同一个Host拥有多个网络名称。示例配置如下:

<Host name="web1.mysite.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
    <Alias>web2.mysite.com</Alias>
</Host>

这样,我们可以同时通过web1.mysite.com和web2.mysite.com两个域名访问当前Host下的应用(当然,需要确保DS中添加了相关配置,以便这两个域名可以定向到当前的主机)。

2.7 Context

Context用于配置一个Web应用,它支持的内嵌元素为:CookieProcessor、Loader、Manager、Realm、Resources、WatchedResource、JarScanner、Valve。

CookieProcessor用于将HTTP请求中的Cookie头信息转换为javax.servlet.http.Cookie对象,或者将Cookie对象转换为HTTP响应中的Cookie头信息。如不指定,将默认使用org.apache.tomcat.util.http.Rfc6265CookieProcessor

Loader用于配置当前Context对应的Web应用的类加载器。如不指定,将默认为org.apache.catalina.loader.WebappLoader

Manager 用于配置当前Web应用的会话管理器。如不指定,将默认为org.apache.catalina.session.StandardManager。会话管理器存在独立启动和集群两种方式。

Resources用于配置Web应用的有效资源(类文件、JAR文件、HTML等静态文件、JSP等)。除非Web应用部分文件位于Web根目录之外,或存储于其他文件系统、数据库或者版本控制库,一般不需要额外添加资源,此时Tomcat会自动创建一个默认的文件系统,可以满足绝大多数的需要。

WatchedResource用于配置自动加载文件检测。当指定文件发生更新时,Web应用将会自动重新加载。对于每个Web应用,Tomcat默认检测的文件是WEB-NF/web.xml、$CATALINA_BASE/conf/web.xml。

JarScanner用于配置Web应用JAR包以及目录扫描器,扫描Web应用的TLD及web-fragment.xml文件。如不配置,默认使用org.apache.tomcat..util.scan.StandardJarScanner.

一个简单的Context配置如下:

<Context docBase="myApp" path="/myApp">
</Context>
  • docBase: Web应用目录或者WAR包的部署路径。可以是绝对路径,也可以是相对于HostappBase的相对路径。

  • path: Web应用的Contexth路径,用于匹配请求地址的起始部分以选择合适的Web应用来处理请求。对于示例,如果我们的Host名为localhost,那么该Web应用的根地址为:http://localhost:8080/myAppa

3. tomcat-users.xml

该配置文件中,主要配置的是Tomcat的用户、角色等信息,用来控制Tomcat中manager,host-manager的访问权限。

4. context.xml

此处的context.xml文件既指$CATALINA BASE/conf/context.xml,又指Web应用中的META- NF/context.xml文件。前面我们说明过,前者配置所有Web应用的公共信息,后者配置每个Web应用的定制化信息。它们的根节点为<Context>,配置方式与<Host>下的<Context>元素完全相同,此处不再赘述。

参考文章

tomcat-9.0.60-src源码解析 
Tomcat架构解析