Tomcat Server.xml配置详细解释

目录

Tomcat 是一个 HTTP server。同时,它也是一个 serverlet 容器,可以执行 java 的 Servlet,也可以把 JavaServer Pages(JSP)和 JavaServerFaces(JSF)编译成 Java Servlet。它的模型图如下:

image-20211115193643613

给个生产环境 server.xml 的例子:

 1<?xml version='1.0' encoding='utf-8'?>
 2<Server port="-1" 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
 9  <GlobalNamingResources>
10    <Resource name="UserDatabase" auth="Container"
11              type="org.apache.catalina.UserDatabase"
12              description="User database that can be updated and saved"
13              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
14              pathname="conf/tomcat-users.xml" />
15  </GlobalNamingResources>
16
17  <Service name="Catalina">
18    <Connector port="8080" 
19               server="www.rendoumi.com" 
20               protocol="org.apache.coyote.http11.Http11NioProtocol"
21               maxHttpHeaderSize="8192"
22               acceptCount="500"
23               maxThreads="1000" 
24               minSpareThreads="200"
25               enableLookups="false" 
26               redirectPort="8443"
27               connectionTimeout="20000"
28               relaxedQueryChars="[]|{}@!$*()+'.,;^\`&quot;&lt;&gt;"
29               disableUploadTimeout="true" 
30               allowTrace="false"
31               URIEncoding="UTF-8" 
32               useBodyEncodingForURI="true" />  
33
34    <Engine name="Catalina" defaultHost="localhost">
35      <Realm className="org.apache.catalina.realm.LockOutRealm">
36        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
37               resourceName="UserDatabase"/>
38      </Realm>
39      <Host name="localhost" appBase="webapps" unpackWARs="false" autoDeploy="false">
40          <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access_log." suffix=".txt"  
41                fileDateFormat="yyyy-MM-dd"
42                pattern="%a|%A|%T|%{X-Forwarded-For}i|%l|%u|%t|%r|%s|%b|%{Referer}i|%{User-Agent}i " resolveHosts="false"/> 
43          <Context path="" docBase="/export/servers/tomcat/webapps/web" /> 
44      </Host>
45
46    </Engine>
47  </Service>
48</Server>

分解开来一部分一部分的看:

Server

Server 第2行,是最大且必须唯一的组件。表示一个 Tomcat 的实例,它可以包含多个 Services,而每个 Service 都可以有自己的 Engine 和 connectors。

1<Server port="8005" shutdown="SHUTDOWN"> ...... </Server>

注意上面,我们把缺省的 port=“8005” 改成了 “-1”,这样防止从8005重启,避免安全问题。

Listeners

一个 Server 容器拥有若干 Listeners (行 3-7)。一个 Listener 监听并回应特定的事件.

  • 例如 GlobalResourcesLifecycleListener 就设置了 global resources,这样就可以使用 JNDI 来存取像数据库这种资源。

    1<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
    
Global Naming Resources

<GlobalNamingResources> (行 9-15) 定义了 JNDI (Java Naming and Directory Interface) 资源,这个是 LDAP 的东西,允许 java 软件通过目录发现对象和属性值。

缺省定义了一个 UserDatabase 的 JNDI 资源(行 10-14),这个对象其实是一个内存数据库,保存着从 conf/tomcat-users.xml 中加载上来的用户认证数据。

1<GlobalNamingResources>
2  <Resource name="UserDatabase" auth="Container"
3            type="org.apache.catalina.UserDatabase"
4            description="User database that can be updated and saved"
5            factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
6            pathname="conf/tomcat-users.xml" />
7</GlobalNamingResources>

我们可以再定义一个 Mysql 之类的 JNDI 来保存 mysql 数据库连接信息,用来实现连接池

Services

Service 用来关联多个 ConnectorsEngine。缺省的配置是配了一个 叫做 CatalinaService ,Catalinna 缺省配了两个 Connectors,一个是8080的HTTP,一个是8009的AJP。

1<Service name="Catalina"> 
2    <Connector port="8080" protocol="HTTP/1.1"
3               connectionTimeout="20000"
4               redirectPort="8443" />
5    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
6</Service>

注意最上面的配置,我们取消了8009的AJP,这个协议现在基本没人用,取消掉也避免安全问题。

下面给出一个 SSL 8443 的 connectors 的例子

1    <Connector port="8443" maxHttpHeaderSize="8192" SSLEnabled="true" server="Rendoumi"
2               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
3               enableLookups="false" disableUploadTimeout="true"
4               acceptCount="100" scheme="https" secure="true" clientAuth="false"
5               URIEncoding="UTF-8"
6               sslProtocol="SSL"
7               ciphers="SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA"
8               keystoreFile="/export/servers/tomcat/rendoumi.keystore"
9               keystorePass="Fuck2020" />
Containers 概念

Tomcat 的容器概念,Tomcat认为 Engine, Host, ContextCluster处在同一个容器中. 最顶层的是 Engine; 最底层是Context

另外像 RealmValve,也可以放在容器中

Engine

Engine 是容器的顶端,可以包含有若干 Hosts。我们可以配置 tomcat 服务多个虚拟主机。下面配置就是服务本机的一个服务。

1<Engine name="Catalina" defaultHost="localhost">

Catalina Engine 从 HTTP connector 处接收到客户端的 HTTP 请求,根据请求头中 Host: xxx 的内容,把请求路由到某个具体的 Host上。

Realm

Realm 本质是一个数据库,是用来保存用户名、密码、认证角色的东西。

1<Realm className="org.apache.catalina.realm.LockOutRealm">
2  <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
3</Realm>
Hosts

Host 定义了虚拟主机,可以定义多个虚拟主机。其中 appBase 千万不能为空,否则就可以读到 tomcat 的所有文件,就出线上事故大 Bug 了!!!

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

我们最上面的生产配置,不自解压,也不自动部署。

Valve

Valve 是用来拦截 HTTP requests的,做预处理后再交给下一个组件,它能在 Engine, Host, Context 中被定义。下面的例子就是在 Engine 中做了拦截,定义了日志格式,交给下一个日志处理组件做处理。

缺省配置

1<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
2       prefix="localhost_access_log." suffix=".txt"
3       pattern="%h %l %u %t &quot;%r&quot; %s %b" />

我们的配置修改了缺省的日志格式,多了很多明细的内容,改变了分割符:

1<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 
2       prefix="access_log." suffix=".txt"  
3       fileDateFormat="yyyy-MM-dd"
4       pattern="%a|%A|%T|%{X-Forwarded-For}i|%l|%u|%t|%r|%s|%b|%{Referer}i|%{User-Agent}i " resolveHosts="false"/> 
Context

Context定义了具体的访问路径,一定要指定 docBase !!!大家一定要记住 appBasedocBase 不同为空!!!

1<Context path="" docBase="/export/servers/tomcat/webapps/web" /> 

如上,我们就配好了一个生产环境的 server.xml ,注意,这个 xml 文件是可以放在解开的tomcat压缩包 apache-tomcat-8.5.64 目录之外的。

我们再另外编写一个启动文件 start.sh:

1#!/bin/sh
2export JAVA_OPTS="-server -Xms1024m -Xmx2048m  -Djava.awt.headless=true -Dsun.net.client.defaultConnectTimeout=60000 -Dsun.net.client.defaultReadTimeout=60000 -Djmagick.systemclassloader=no -Dnetworkaddress.cache.ttl=300 -Dsun.net.inetaddr.ttl=300"
3export CATALINA_HOME=/export/servers/tomcat/apache-tomcat-8.5.64
4
5cd /export/servers/tomcat/
6$CATALINA_HOME/bin/catalina.sh start -config "/export/servers/tomcat/server.xml"

这样,我们的启动文件和配置文件,就和 tomcat 目录分离了,这样做的好处是如果 tomcat 需要升级,那么直接解压换目录即可。

我们可以做个软链接 tomcat 链接到 apache-tomcat-8.5.64,这样更方便操作。


GlusterFS文件系统的优化
Linux下web Pacproxy的用法
comments powered by Disqus