Tomcat 配置文件详解

时间:2024-02-01 15:44:13

打开Tomcat的配置目录,我们会发现下面的配置文件:

  • server.xml:Tomcat的主配置文件,包含Service, Connector, Engine, Realm, Valve, Hosts主组件的相关配置信息;
  • web.xml:遵循Servlet规范标准的配置文件,用于配置servlet,并为所有的Web应用程序提供包括MIME映射等默认配置信息;
  • context.xml:所有host的默认配置信息;
  • logging.properties:日志相关配置;
  • tomcat-users.xml:Realm认证时用到的相关角色、用户和密码等信息;Tomcat自带的manager默认情况下会用到此文件;在Tomcat中添加/删除用户,为用户指定角色等将通过编辑此文件实现;
  • catalina.policy:Java相关的安全策略配置文件,在系统资源级别上提供访问控制的能力,以安全模式启动Tomcat会使用这个配置
  • catalina.properties:Tomcat内部package的定义及访问相关的控制,也包括对通过类装载器装载的内容的控制;Tomcat在启动时会事先读取此文件的相关设置;
  • jaspic-providers.xml:用户认证配置文件

这篇博客就来介绍下这几个配置文件的作用,以及常用的配置选项。

server.xml配置

server.xml是Tomcat的主配置文件,可以对Service, Connector, Engine, Realm, Valve, Hosts等主组件进行相关配置。

<!-- port: 接收shutdown指令的端口,默认仅允许通过本机访问,默认为8005;
     shutdown:发往此Server用于实现关闭tomcat实例的命令字符串,默认为SHUTDOWN;
     使用方式:telnet localhost 8005, 输入SHUTDOWN即可关闭tomcat   
  
     如果你不配置这两个属性,Tomcat的这种关闭机制还是会运行的。你不想暴露这种关闭机制的
     话,可以将端口设置成poer=-1,shutdown设置成一个复杂的字符串,比如shutdown="xscdeww#12"
 -->
<Server port="8005" shutdown="SHUTDOWN">
  <!-- 默认配置的Listener -->
  <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" />

  <!-- 应用于整个服务器的JNDI映射,此可以避免每个Web应用程序都需要在各自的web.xml创建,这在web应用程序        以WAR的形式存在时尤为有用。
   -->
  <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是多个Connector和单个Container的组合。Container是一个抽象的概念,由Engine, Realm,        Valve和Hosts主组组成。
       在server.xml配置文件中可以同时配置多个Service标签
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread         pools
     --> 
    <!-- 默认情况下,每个连接器connector会使用自己创建的线程池,我们也可以配置多个线程池让连接器共享-->
    <!-- 如果想让连接器connector组件使用这个线程池,需要在连接器组件中配置executor属性.
         另外,Executor元素的配置应该放在Connector配置的前面,这样才会先加载Executor的配置。
        
         Executor的主要属性包括:
          - name:该线程池的名称id
          - maxThreads:线程池中最大活跃线程数,默认值200(Tomcat7和8都是)
          - minSpareThreads:线程池中保持的最小线程数,最小值是25
          - maxIdleTime:线程空闲的最大时间,当空闲超过该值时关闭线程(除非线程数小于
                         minSpareThreads),单位是ms,默认值60000(1分钟)
          - daemon:是否后台线程,默认值true
          - threadPriority:线程优先级,默认值5
          - namePrefix:线程名字的前缀,线程池中线程名字为:namePrefix+线程编号
     -->
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
              maxThreads="150" minSpareThreads="4"/>
    
    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <!-- Connector是Tomcat中请求接收和响应返回的端点,Tomcat中支持HTTP、AJP和APR等协议。
         下面的配置定义了一个支持Http协议的连接器,监听8080端口

         Connector组件支持以下组件的配置:
          - address:指定连接器监听的地址,默认为所有地址,即0.0.0.0;
          - port:监听的端口,默认为0;
          - protocol:连接器使用的协议,默认为HTTP/1.1,定义AJP协议时通常为AJP/1.3;
          - connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000,即1分钟;
          - maxThreads:支持的最大并发连接数,默认为200;
          - redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,
                          则转发至此属性定义的端口;
          - enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名;
                           默认为true;
          - acceptCount:设置等待队列的最大长度;
          - executor:指定共享的线程池组件;
     -->
    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000"
               redirectPort="8443"
               executor="tomcatThreadPool" />
    
    <!-- 下面是进行支持Https的配置 -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the
         AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!--
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />
    -->
      
      
    <!-- Tomcat内部有4个级别的容器,分别是Engine、Host、Context和Wrapper。Engine代表全局Servlet引          擎,每个Service组件只能包含一个Engine容器组件,但Engine组件可以包含若干Host容器组件 
     -->
    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->
      
    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <!-- 配置虚拟主机,可以配置多个-->
      <!-- 一个Host下面可以有多个Context,也就是可以部署多个Webapp应用,一个webapp对应一个Context,用不同的ContextPath区分 
      -->
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

        <!-- Host下面也可以配置Context相关的配置 -->
      </Host>
    </Engine>
  </Service>
</Server>

web.xml配置

Tomcat的conf目录下面的web.xml配置文件和我们平时应用中WEB-INF下面的配置web.xml功能一致,只是Tomcat下面的这个配置文件用来配置所有应用通用的配置,对所用应用生效

  • 配置默认servlet,Jsp处理器和一些其他的filter;
  • 为所有的Web应用程序提供包括MIME映射;
  • 并设置欢迎页面。

通常Tomcat下面的这个配置文件不需要我们自己另行做额外配置。

</web-app> 
   <!-- 默认的Servlet,如果请求没有匹配到任何一个Sevlet,就是匹配到这个Servlet -->
   <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

   <!-- 对JSP页面的支持 --> 
   <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>
 
    <!-- 对ssi功能的至此 -->
    <servlet>
        <servlet-name>ssi</servlet-name>
        <servlet-class>
          org.apache.catalina.ssi.SSIServlet
        </servlet-class>
        <init-param>
          <param-name>buffered</param-name>
          <param-value>1</param-value>
        </init-param>
        <init-param>
          <param-name>debug</param-name>
          <param-value>0</param-value>
        </init-param>
        <init-param>
          <param-name>expires</param-name>
          <param-value>666</param-value>
        </init-param>
        <init-param>
          <param-name>isVirtualWebappRelative</param-name>
          <param-value>false</param-value>
        </init-param>
        <load-on-startup>4</load-on-startup>
    </servlet>
    
    <!-- 对cgi请求的支持 -->
    <servlet>
        <servlet-name>cgi</servlet-name>
        <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
        <init-param>
          <param-name>cgiPathPrefix</param-name>
          <param-value>WEB-INF/cgi</param-value>
        </init-param>
        <load-on-startup>5</load-on-startup>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ssi</servlet-name>
        <url-pattern>*.shtml</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>cgi</servlet-name>
        <url-pattern>/cgi-bin/*</url-pattern>
    </servlet-mapping>

    
    <!-- 一些内置的Filter,Filter默认是不打开的,要打开的话需要去Tomcat的web.xml中放开注释-->
    <!-- 另外,这个这些Filter默认都是可以配置很多初始化参数的,具体参数请参考原始配置中的注释,这边
         没有贴出来
     -->
     <!-- A filter that sets various security related HTTP Response headers.   -->
     <filter>
        <filter-name>httpHeaderSecurity</filter-name>
        <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
        <async-supported>true</async-supported>
     </filter>
     
      <!-- A filter that sets character encoding that is used to decode 
           parameters in a POST request (对post请求生效)
      -->
    <filter>
        <filter-name>setCharacterEncodingFilter</filter-name>
        <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <async-supported>true</async-supported>
    </filter>
    
    <!-- 对于bad request,直接返回 -->
    <filter>
        <filter-name>failedRequestFilter</filter-name>
        <filter-class>
          org.apache.catalina.filters.FailedRequestFilter
        </filter-class>
        <async-supported>true</async-supported>
    </filter>
 
    <!-- 实现ssi功能 -->
    <!-- 上面还提供了实现ssi功能的servlet,不要同时开启两个,只要使用其中一个就行了 -->
    <filter>
        <filter-name>ssi</filter-name>
        <filter-class>
          org.apache.catalina.ssi.SSIFilter
        </filter-class>
        <init-param>
          <param-name>contentType</param-name>
          <param-value>text/x-server-parsed-html(;.*)?</param-value>
        </init-param>
        <init-param>
          <param-name>debug</param-name>
          <param-value>0</param-value>
        </init-param>
        <init-param>
          <param-name>expires</param-name>
          <param-value>666</param-value>
        </init-param>
        <init-param>
          <param-name>isVirtualWebappRelative</param-name>
          <param-value>false</param-value>
        </init-param>
    </filter>
  
    <filter-mapping>
        <filter-name>httpHeaderSecurity</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    <filter-mapping>
        <filter-name>setCharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>failedRequestFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>ssi</filter-name>
        <url-pattern>*.shtml</url-pattern>
    </filter-mapping>

    <!-- 默认的session过期时间-->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <!-- mime的mapping信息-->
    ...
    <mime-mapping>
        <extension>123</extension>
        <mime-type>application/vnd.lotus-1-2-3</mime-type>
    </mime-mapping>
    ...
    <!-- 配置欢迎页面 -->
	<welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

上面的web.xml是Tomcat提供的通用的配置。一般情况下,webApp也都会有自己的web.xml配置,存放在WEB-INF下面,这边也给出一个webApp的配置:

!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<!--一个web应用对应一个ServletContext实例,这个实例是应用部署启动后,servlet容器为应用创建的。
    ServletContext实例包含了所有servlet共享的资源信息。通过提供一组方法给servlet使用,用来
    和servlet容器通讯,比如获取文件的MIME类型、分发请求、记录日志等。
    http://www.cnblogs.com/nantang/p/5919323.html 
-->
<web-app>
	<display-name>Archetype Created Web Application</display-name>


	<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:beans.spring.xml</param-value>
    </context-param>
	<context-param>
		<param-name>webAppRootKey</param-name>
		<param-value>project.root.path</param-value>
	</context-param>


	<!-- 将项目的绝对路径放到系统变量中 -->
	<listener>
		<listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
	</listener>
	<!--初始化Spring IOC容器,并将其放到servletContext的属性当中-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener> 
     
	<!-- 配置SPRINGMVC-->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.spring.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<!-- 这边不建议写成/* -->
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

context.xml配置

context组件是host组件的子组件。context.xml中的配置是所有host组件的通用配置,Tomcat的conf目录下的context.xml的内容,如下。(通常,这个配置文件也不需要我们做另外的配置)

<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
</Context>

logging.properties配置

Tomcat日志相关的配置文件,不是重点。

tomcat-users.xml配置

Tomcat提供了一个管理控制台,在控制台的manager的管理页面,我们能够查看到所有部署的应用的运行状态、也能管理应用的运行。当然,我们也能通过这个界面进行应用部署。

当然,想要通过这个界面进行应用管理和部署,需要用户进行登陆。这些配置就是在tomcat-users.xml中进行配置的。

Tomcat中支持的所有的用户管理角色有:

<!-- 相当于admin角色,网站管理员角色 -->
<role rolename="admin-gui"/> 
<role rolename="admin-script"/>
<!--允许访问html接口(即URL路径为/manager/html/*)-->
<role rolename="manager-gui"/>
<!-- 允许访问纯文本接口(即URL路径为/manager/text/*) -->
<role rolename="manager-script"/>
<!-- 允许访问JMX代理接口(即URL路径为/manager/jmxproxy/*)-->
<role rolename="manager-jmx"/>
<!-- 允许访问Tomcat只读状态页面(即URL路径为/manager/status/*)-->
<role rolename="manager-status"/>

配置用户的角色、登录名和密码,需要在tomcat-users.xml中进行配置。

如果想要访问manager页面需要配置:

<role rolename="manager-gui"/>
<user username="admin" password="password" roles="manager-gui"/>

如果需要使用到远程部署等功能,需要添加上:

<role rolename="manager-script" />
<user username="admin" password="password" roles="manager-gui,manager-script"/>

下面给出一个比较完整的配置列子,生产环境需要根据具体需求配置用户和角色。

  <!-- 相当于admin角色,网站管理员角色 -->
  <role rolename="admin-gui"/> 
  <role rolename="admin-script"/>
  <!--允许访问html接口(即URL路径为/manager/html/*)-->
  <role rolename="manager-gui"/>
  <!-- 允许访问纯文本接口(即URL路径为/manager/text/*) -->
  <role rolename="manager-script"/>
  <!-- 允许访问JMX代理接口(即URL路径为/manager/jmxproxy/*)-->
  <role rolename="manager-jmx"/>
  <!-- 允许访问Tomcat只读状态页面(即URL路径为/manager/status/*)-->
  <role rolename="manager-status"/>
  <user username="admin" password="admin123" roles="admin-gui,admin-script"/>
  <user username="manager" password="manager123" roles="manager-gui,manager-script"/>

jaspic-providers.xml配置

关于jaspic-providers.xml配置,作用和tomcat-user.xml类似,都是实现用户认证的。Tomcat 实现了 JASPIC 1.1 Maintenance Release B 标准,并通过这个配置文件集成第三方 JASPIC 身份验证。

但是这个认证方式不怎么使用,大家不用太关注这个配置。

catalina.properties和catalina.policy配置

这里面的很多配置是在Tomcat以安全模式启动时才会生效的,平时我们大多情况下都不会以安全模式启动Tomcat,所有很多配置可能用不太到。关于对Java中SecurityManager的介绍,大家可以参考下这边文章,比较浅显易懂。(这边留个问题,是否需要使用安全模式启动Java应用?)

不过catalina.properties中关于公共组件的配置,还是比较有用的,我们可以看下。

catalina.properties中的配置分为四个部分:

  • 第一部分:安全设置

    package.access

    package.definition

  • 第二部分:类加载设置(可以重点关注下

    common.loader

    server.loader

    shared.loader

  • 第三部分:不需要扫描的类设置

    tomcat.util.scan.DefaultJarScanner.jarsToSkip

    org.apache.catalina.startup.ContextConfig.jarsToSkip

    org.apache.catalina.startup.TldConfig.jarsToSkip

  • 第四部分:字符缓存设置

    tomcat.util.buf.StringCache.byte.enabled
    tomcat.util.buf.StringCache.char.enabled
    tomcat.util.buf.StringCache.trainThreshold
    tomcat.util.buf.StringCache.cacheSize

Tomcat加载类的顺序是:

Bootstrap--->System--->/WEB-INF/classes---> /WEB-INF/lib/*.jar---> Common--->Server--->Shared

所以加载完项目的WEB-INF的lib下面的Jar包后回来加载common下面的包。关于common loader,tomcat已经做了相关配置:

common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"

上面的配置表示,common loader会加载catalina.base和catalina.home下面的class类和Jar包中的类。

关于server.loader和shared.loader,Tomcat并没有做出明确的配置,我们可以自己进行配置。比如:

server.loader=${catalina.base}/server/classes,${catalina.base}/server/lib/*.jar
shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar

上面的含义和common loader的含义一致。

平时我们的一些组件假如需要让所有Web应用依赖的话,我们就可以放在common.loader、server.loader和shared.loader指定的目录下面。

关于Connector组件参数的额外说明

再回顾一下Tomcat处理请求的过程:在accept**队列中接收连接(当客户端向服务器发送请求时,如果客户端与OS完成三次握手建立了连接,则OS将该连接放入accept队列);在连接中获取请求的数据,生成request;调用servlet容器处理请求;返回response****。**

相对应的,Connector中的几个参数功能如下:

1、acceptCount

accept队列的长度;当accept队列中连接的个数达到acceptCount时,队列满,进来的请求一律被拒绝。默认值是100。

2、maxConnections

Tomcat在任意时刻接收和处理的最大连接数。当Tomcat接收的连接数达到maxConnections时,Acceptor线程不会读取accept队列中的连接;这时accept队列中的线程会一直阻塞着,直到Tomcat接收的连接数小于maxConnections。如果设置为-1,则连接数不受限制。

默认值与连接器使用的协议有关:NIO的默认值是10000,APR/native的默认值是8192,而BIO的默认值为maxThreads(如果配置了Executor,则默认值是Executor的maxThreads)。

在windows下,APR/native的maxConnections值会自动调整为设置值以下最大的1024的整数倍;如设置为2000,则最大值实际是1024。

3、maxThreads

请求处理线程的最大数量。默认值是200(Tomcat7和8都是的)。如果该Connector绑定了Executor,这个值会被忽略,因为该Connector将使用绑定的Executor,而不是内置的线程池来执行任务。

maxThreads规定的是最大的线程数目,并不是实际running的CPU数量;实际上,maxThreads的大小比CPU核心数量要大得多。这是因为,处理请求的线程真正用于计算的时间可能很少,大多数时间可能在阻塞,如等待数据库返回数据、等待硬盘读写数据等。因此,在某一时刻,只有少数的线程真正的在使用物理CPU,大多数线程都在等待;因此线程数远大于物理核心数才是合理的。

换句话说,Tomcat通过使用比CPU核心数量多得多的线程数,可以使CPU忙碌起来,大大提高CPU的利用率。

4、参数设置

(1)maxThreads的设置既与应用的特点有关,也与服务器的CPU核心数量有关。通过前面介绍可以知道,maxThreads数量应该远大于CPU核心数量;而且CPU核心数越大,maxThreads应该越大;应用中CPU越不密集(IO越密集),maxThreads应该越大,以便能够充分利用CPU。当然,maxThreads的值并不是越大越好,如果maxThreads过大,那么CPU会花费大量的时间用于线程的切换,整体效率会降低。

(2)maxConnections的设置与Tomcat的运行模式有关。如果tomcat使用的是BIO,那么maxConnections的值应该与maxThreads一致;如果tomcat使用的是NIO,那么类似于Tomcat的默认值,maxConnections值应该远大于maxThreads。

(3)通过前面的介绍可以知道,虽然tomcat同时可以处理的连接数目是maxConnections,但服务器中可以同时接收的连接数为maxConnections+acceptCount 。acceptCount的设置,与应用在连接过高情况下希望做出什么反应有关系。如果设置过大,后面进入的请求等待时间会很长;如果设置过小,后面进入的请求立马返回connection refused。