Tomcat配置文件詳解
打開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 "%r" %s %b" />
</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"
"//java.sun.com/dtd/web-app_2_3.dtd" >
<!--一個web應用對應一個ServletContext實例,這個實例是應用部署啟動後,servlet容器為應用創建的。
ServletContext實例包含了所有servlet共享的資源資訊。通過提供一組方法給servlet使用,用來
和servlet容器通訊,比如獲取文件的MIME類型、分發請求、記錄日誌等。
//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。