3

Tomcat server.xml配置详细解释

 2 years ago
source link: https://zhangrr.github.io/posts/20211115-tomcat_config/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Tomcat Server.xml配置详细解释

2021-11-15 3 分钟阅读

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

image-20211115193643613

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

<?xml version='1.0' encoding='utf-8'?>
<Server port="-1" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> 
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <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" 
               server="www.rendoumi.com" 
               protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxHttpHeaderSize="8192"
               acceptCount="500"
               maxThreads="1000" 
               minSpareThreads="200"
               enableLookups="false" 
               redirectPort="8443"
               connectionTimeout="20000"
               relaxedQueryChars="[]|{}@!$*()+'.,;^\`"<>"
               disableUploadTimeout="true" 
               allowTrace="false"
               URIEncoding="UTF-8" 
               useBodyEncodingForURI="true" />  

    <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="false" autoDeploy="false">
          <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access_log." suffix=".txt"  
                fileDateFormat="yyyy-MM-dd"
                pattern="%a|%A|%T|%{X-Forwarded-For}i|%l|%u|%t|%r|%s|%b|%{Referer}i|%{User-Agent}i " resolveHosts="false"/> 
          <Context path="" docBase="/export/servers/tomcat/webapps/web" /> 
      </Host>

    </Engine>
  </Service>
</Server>

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

Server

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

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

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

Listeners

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

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

    <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 中加载上来的用户认证数据。

<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>

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

Services

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

<Service name="Catalina"> 
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
</Service>

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

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

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

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

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

Engine

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

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

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

Realm

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

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

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

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

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

Valve

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

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

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

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 
       prefix="access_log." suffix=".txt"  
       fileDateFormat="yyyy-MM-dd"
       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 不同为空!!!

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

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

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

#!/bin/sh
export 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"
export CATALINA_HOME=/export/servers/tomcat/apache-tomcat-8.5.64

cd /export/servers/tomcat/
$CATALINA_HOME/bin/catalina.sh start -config "/export/servers/tomcat/server.xml"

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK