Tomcat系列1-配置文件

tomcat配置文件目錄是conf目錄,主要配置文件有5個,下面一個個分析下。

1.context.xml

Context.xml是Tomcat公用的環境配置,tomcat服務器會定時去掃描這個文件。一旦發現文件被修改(時間戳改變了),就會自動重新加載這個文件,而不需要重啓服務器。不同於server.xml 文件是不可動態重加載的資源,服務器一旦啓動了以後,要修改這個文件,就得重啓服務器才能重新加載。

<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
	//監聽web.xml文件,文件變動後重新加載
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

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

2.web.xml

我們web應用的默認配置文件。比如:
默認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>

默認JSPServlet

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

Servlet可以處理的請求

<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

可以處理的請求類型,只要只貼出部分我們常見的請求類型

json application/json jsonml application/jsonml+json jspf text/plain

3.tomcat-users.xml

這個是tomcat自動的應用管理工具Tomcat Manager訪問的用戶權限配置。

 <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
  <user username="role1" password="<must-be-changed>" roles="role1"/>

tomcat內部的分爲哪幾個角色,每個角色可以訪問什麼資源,這些在哪裏看?
在tomcat目錄下的webapps\manager\WEB-INF目錄下面的web.xml文件。這個就是tomcat自動管理應用的web.xml文件。
其中有security-role節點,定義了有哪些角色

<security-role>
    <description>
      The role that is required to access the HTML Manager pages
    </description>
    <role-name>manager-gui</role-name>
  </security-role>
  <security-role>
    <description>
      The role that is required to access the text Manager pages
    </description>
    <role-name>manager-script</role-name>
  </security-role>
  <security-role>
    <description>
      The role that is required to access the HTML JMX Proxy
    </description>
    <role-name>manager-jmx</role-name>
  </security-role>
  <security-role>
    <description>
      The role that is required to access to the Manager Status pages
    </description>
    <role-name>manager-status</role-name>
  </security-role>

還有個security-constraint節點定義了每個角色可以訪問什麼資源

<security-constraint>
    <web-resource-collection>
      <web-resource-name>HTML Manager interface (for humans)</web-resource-name>
      <url-pattern>/html/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
       <role-name>manager-gui</role-name>
    </auth-constraint>
  </security-constraint>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Text Manager interface (for scripts)</web-resource-name>
      <url-pattern>/text/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
       <role-name>manager-script</role-name>
    </auth-constraint>
  </security-constraint>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>JMX Proxy interface</web-resource-name>
      <url-pattern>/jmxproxy/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
       <role-name>manager-jmx</role-name>
    </auth-constraint>
  </security-constraint>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Status interface</web-resource-name>
      <url-pattern>/status/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
       <role-name>manager-gui</role-name>
       <role-name>manager-script</role-name>
       <role-name>manager-jmx</role-name>
       <role-name>manager-status</role-name>
    </auth-constraint>
  </security-constraint> 

4.jaspic-providers.xml

這個配置文件集成第三方JASPIC身份驗證,我們不常用,這裏不分析。

5.server.xml

server.xml是tomcat的核心配置文件。先大致看一眼,再分析。

<?xml version="1.0" encoding="UTF-8"?>
//server是頂層元素,只能有一個
<Server port="8005" 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將Connector和Engine包裝起來,統一對外提供服務。一個server可以有不同的service
	//不同的service監聽不同的端口
	<Service name="Catalina">
		//線程池
		<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4" />
		//Connector監聽端口爲8080,處理協議HTTP1.1協議
		//創建Request和Response對象,然後分配線程讓Engine來處理這個請求
		<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
		<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
		//處理Connector發送的請求,並把相應返回給Connector
		<Engine name="Catalina" defaultHost="localhost">

			<Realm className="org.apache.catalina.realm.LockOutRealm">
				<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
					resourceName="UserDatabase" />
			</Realm>
			//虛擬節點,處理對應域名或者ip的請求
			<Host name="localhost" appBase="webapps" unpackWARs="true"
				autoDeploy="true">
				//日誌打印
				<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>
		</Engine>
	</Service>
</Server>

5.1 server元素

整個配置文件的根元素,代表整個tomcat容器,一個tomcat中只能有一個server元素。Server的作用就是提供一個接口,讓客戶端能夠訪問內部Service集合,同時維護所有的Service的生命週期,包括初始化、結束服務以及如何找到客戶端要訪問的Service。
屬性:

  • className:server元素對應的處理類,默認是StandardServer。tomcat的server實現類必須實現org.apache.catalina.Server接口
  • Port:Tomcat將在這個接口監聽關閉服務器的命令
  • Shutdown:關閉Tomcat服務器的命令字符串

5.2 Listener元素

Listener就是監聽器,監聽特定事件發生並執行特定的操作。監聽器可以在Server、Engine、Host或Context中。
屬性:

  • className:監聽器的具體實現類,監聽器必須實現org.apache.catalina.LifecycleListener接口。

介紹幾個常用監聽器:

  • VersionLoggerListener:Tomcat啓動時,記錄Tomcat、Java和操作系統的信息,必須配置在第一個
  • AprLifecycleListener:Tomcat啓動時,檢查APR庫,如果存在則加載
  • JasperListener:Web應用啓動之前初始化Jasper。Jasper是JSP引擎,把JSP文件解析成java文件,然後編譯成class文件供JVM使用
  • JreMemoryLeakPreventionListener:與類加載器導致的內存泄露有關。
  • GlobalResourcesLifecycleListener:通過該監聽器,初始化GlobalNamingResources標籤中定義的全局JNDI資源
  • ThreadLocalLeakPreventionListener:當Web應用因ThreadLocal導致的內存泄露而要停止時,該監聽器會觸發線程池中線程的更新。只有當Context元素的renewThreadsWhenStoppingContext屬性設置爲true時,該監聽器纔有效

5.3 Service元素

service就是將其內部的Connector和Engine包裝起來,統一對外提供服務。一個Service可以包含多個Connector,但是隻能包含一個Engine。其中Connector的作用是從客戶端接收請求,然後轉交給Engine處理,Engine處理完成後將響應返回給Connector,Connector再返回給客戶端。

5.4 Connector元素

Connector就是連接器。作用是接收客戶端的連接請求,創建Request和Response對象,然後分配線程讓Engine來處理,並把產生的Request和Response對象傳給Engine。Engine處理完後將Response返回給Connector,Connector再返回給客戶端。
屬性:

  • allowTrace:是否允許HTTP的TRACE方法,默認爲false
  • enableLookups:如果爲true,調用request.getRemoteHost()遠程主機的主機名。如果爲false,則直接返回IP地址
  • maxPostSize:POST請求的最大數量,沒有指定默認爲2097152
  • protocol:請求協議,比如HTTP1.1,或者AJP/1.3
  • redirectPort:重定向端口,比如連機器不支持SSL,請請求轉發給這個端口
  • secure:SSL連接器中設置爲true,默認爲false;
  • URIEncoding:URL編碼,默認爲ISO-8859-1;
  • acceptCount:當accept隊列中連接的個數達到acceptCount時,後續請求一律被拒絕。默認值是100
  • bufferSize:輸入流緩衝區大小,默認2048字節;
  • compressableMimeType:MIME的列表,默認是text/html,text/xml,text/plain;
  • compression:是否對響應數據壓縮。off是禁止壓縮,on是允許壓縮。force是所有情況下都進行壓縮,默認不壓縮
  • connectionTimeout:連接超時時間
  • maxHttpHeaderSize:HTTP請求和響應頭的最大量,默認爲4096字節;
  • maxKeepAliveRequest:長連接最大數
  • port:監聽的端口
  • maxConnections:Tomcat在任意時刻接收和處理的最大連接數
    (1)一個Service可以包含多個Connector,比如```
 //處理以http協議訪問8080端口的請求,當要求請求是https,但請求是http時,重定向到端口號爲8443的Connector
 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
 //處理以AJP協議訪問8009端口的請求。AJP協議負責和其他的HTTP服務器(如Apache)建立連接。
 //Tomcat常用來作爲Servlet/JSP容器,但是對靜態資源的處理速度較慢,不如Apache等HTTP服務器,所以有時會將Tomcat和Apache集成,這時候就會用到這個連接器。
 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

(2)Connector重要參數詳細說明
Connector是處理客戶端連接請求的,分配線程讓Engine處理,所以Connector參數的配置直接影響tomcat的性能,這裏詳細說明下幾個重要的參數。
Connector處理請求分爲BIO和NIO兩種方式。
BiO的處理流程
客戶端通過TCP三次握手和服務器建立連接後,連接請求socket會放入一個accept隊列。Connector中主要通過JIoEndpoint對象處理請求,JIoEndpoint對象維護了Acceptor和Worker。Acceptor負責從accept隊列接收socket,然後從Worker線程池中找出空閒的線程處理socket。如果沒有空閒線程,Acceptor將阻塞。其中如果配置了Executor,使用的是Worker線程池就是Executor,否則是tomcat自帶的線程池。
NiO的處理流程
客戶端通過TCP三次握手和服務器建立連接後,連接請求socket會放入一個accept隊列。Connector中主要通過NIoEndpoint對象處理請求,NIoEndpoint對象維護了Acceptor、Worker和Poller。Acceptor負責從accept隊列接收socket,然後Acceptor將請求放入了一個隊列,Poller從隊列中消費請求,並將該請求註冊到一個Selector選擇器,然後輪詢Selector找到真正有請求數據的,再從Worker線程池中找出空閒的線程處理socket。如果沒有空閒線程則將阻塞。其中如果配置了Executor,使用的是Worker線程池就是Executor,否則是tomcat自帶的線程池。
目前大多數HTTP請求使用的是長連接,也就是說socket在當前請求結束後,socket不會立馬釋放,而是等timeout後再釋放,相應的線程會一直被佔用。使用BIO,有socket連接後直接交給線程處理,不管有沒有讀寫請求,所以Tomcat同時處理的socket數目不能超過最大線程數,性能受到限制。而使用NIO,socket是註冊到Selector選擇器,有讀寫請求後才交給線程處理,所以Tomcat可以同時處理的socket數目可以遠大於最大線程數,併發性能大大提高。
acceptCount、maxConnections、maxThreads參數

  • acceptCount
    accept隊列的長度;當accept隊列中連接的個數達到acceptCount時,隊列滿,進來的請求一律被拒絕。默認值是100。
  • maxConnections
    Tomcat在任意時刻接收和處理的最大連接數。當Tomcat接收的連接數達到maxConnections時,Acceptor線程不會讀取accept隊列中的連接。這時accept隊列中的線程會一直阻塞着,直到Tomcat接收的連接數小於maxConnections。如果設置爲-1,則連接數不受限制。
    NIO的默認值是10000,APR/native的默認值是8192,而BIO的默認值爲maxThreads(如果配置了Executor,則默認值是Executor的maxThreads)。
  • maxThreads
    處理請求線程的最大數量。默認值是200。如果該Connector綁定了Executor,這個值會被忽略,因爲該Connector將使用綁定的Executor,而不是內置的線程池來執行任務。

Executor的主要屬性包括

  • name:該線程池的標記
  • maxThreads:線程池中最大活躍線程數,默認值200(Tomcat7和8都是)
  • minSpareThreads:線程池中保持的最小線程數,最小值是25
  • maxIdleTime:線程空閒的最大時間,當空閒超過該值時關閉線程(除非線程數小於minSpareThreads),單位是ms,默認值60000(1分鐘)
  • daemon:是否後臺線程,默認值true
  • threadPriority:線程優先級,默認值5
  • namePrefix:線程名字的前綴,線程池中線程名字爲:namePrefix+線程編號

5.5 Engine元素

Engine在Service中只能由一個;Engine是Service組件中的請求處理組件。Engine組件從一個或多個Connector中接收請求並處理,並將完成的響應返回給Connector。
Engine、Host和Context都是容器,Engine包含Host,Host包含Context。Engine中至少有一個Host元素,並且必須有一個Host屬性的名字與defaultHost指定的名字相匹配。
屬性:

  • className:Engine元素的實現類,默認是StandardEngine。實現類必須實現org.apache.catalina.Engine接口
  • defaultHost:默認主機名,值必須與Service的name值相匹配
  • name:Engine名稱
  • jvmRoute:在負載勻衡中使用的標識符

5.6 Host元素

Host表示一個虛擬主機。
屬性:

  • appBase:設定應用程序的基目錄,絕對路徑或相對於%CATALINA_HOME%的路徑名
  • autoDeploy:指示Tomcat運行時,如有新的WEB程序在appBase指定的目錄下,是否自動佈署,默認值爲true
  • className:Host元素實現類名,默認是StandardHost。Host實現類必須實現org.apache.catalina.Host接口
  • deployOnStartup:Tomcat啓動時,是否自動部署appBase屬性指定目錄下所有的WEB應用程序,默認值爲true
  • name:虛擬主機名稱
  • deployXML:爲false將不會解析WEB應用程序內部的context.xml,默認值爲true;
  • unPackWARs:是否將Web應用的WAR文件解壓

autoDeploy和deployOnStartup區別

  • deployOnStartup爲true時,Tomcat在啓動時檢查Web應用,檢測到的所有Web應用都是新應用
  • autoDeploy爲true時,Tomcat在運行時定期檢查是否有新的Web應用或Web應用的更新
    應用的新增或者更新的檢查目錄爲Host元素的appBase和xmlBase配置。appBase屬性指定Web應用所在的目錄,默認值是webapps。xmlBase屬性指定Web應用的XML配置文件所在的目錄,默認值爲conf/<engine_name>/<host_name>。

5.7 Context元素

Context代表在特定虛擬主機上運行的一個WEB應用程序,需處理當前WEB應用程序的所有請求,每一個ontext必須使用唯一的上下文路徑。
Context是Host的子容器,每個Host中可以定義任意多的Context元素。
屬性:

  • className:Context元素實現類,默認是StandardContext。Context實現類必須實現org.apache.catalina.Context接口
  • cookies:是否將Cookie應用於Session,默認值爲true
  • crossContext:是否允許跨域訪問
  • docBase:絕對路徑或相對於Host的appBase 屬性的相對路徑,代表WAR包路徑或者應用目錄,注意docBase在appBase目錄時,不需要指定
  • privileged:是否允許Web應用程序使用容器的Servlet
  • path:訪問該Web應用的上下文路徑。一個虛擬主機中,上下文路徑必須唯一
  • reloadable:Tomcat運行時,如果WEB-INF/classes和WEB-INF/lib目錄中有改變,否自動重新加載。對性能影響比較大,慎用
  • cacheMaxSize:靜態資源緩存最大值,以KB爲單位,默認值爲10240KB;
  • cachingAllowed:是否允許靜態資源緩存,默認爲true
  • caseSensitive:資源文件名大小寫是否敏感
  • unpackWAR:是否解壓war包
  • workDir:Servlet指定臨時讀寫的目錄

有時候我們的server.xml配置文件中並沒有Context元素。這是因爲Tomcat開啓了自動部署,這時候path屬性由配置文件(xmlBase目錄下xml文件)的文件名、WAR文件的文件名或應用目錄的名稱自動推導出來。如果名稱是ROOT,則該Web應用是虛擬主機默認的Web應用,此時path屬性推導爲""。

5.8 Valve元素

Valvee在Tomcat中代表了請求處理流水線上的一個組件,Valve可以與Tomcat的容器Engine、Host或Context關聯。不同的Valve有不同的特性,這裏介紹一下上面出現的AccessLogValve。
AccessLogValve的作用是通過日誌記錄其所在的容器中處理的所有請求,在上述文件中Valve放在Host下,可以記錄該Host處理的所有請求。
AccessLogValve的屬性

  • className:Valve實現類
  • directory:日誌存儲的目錄
  • prefix:日誌文件的前綴
  • suffix:日誌文件的後綴
  • pattern:記錄日誌的格式,%h:遠程主機名或IP地址;%l:遠程邏輯用戶名,一般是”-”;%u:授權的遠程用戶名,如果沒有則是”-”;%t:訪問的時間;%r:請求的第一行,即請求方法(get/post等)、uri、及協議;%s:響應狀態,如404等等;%b:響應的數據量,不包括請求頭,如果爲0,則是”-”;%D,含義是請求處理的時間

6.總結

先看下tomcat的架構圖
在這裏插入圖片描述
tomcat中只能由一個server,一個server中可以包含多個service,一個service中只能包含一個Engine,可以包含多個Connector,一個Engine可以包含多個host,一個host中可以包含多個Context。
tomcat處理流程:

  • 客戶端發起請求tomcat容器
  • service找到符合端口和協議的Connector執行
  • Connector創建Request和Response對象,創建線程,交給Engine執行
  • 請求流轉到Engine後,會進入它的pipeline組件,並且經過內部Valve的過濾,然後Engine根據訪問的域名或者ip找到對應host執行
  • 請求流轉到Host後,會進入它的pipeline組件中,並且經過內部Valve的過濾,然後host請求路徑找到對應的Context下的應用
  • 請求流轉到Context後,會進入它的pipeline組件中,並且經過內部Valve的過濾,然後交給Wrapper執行
  • 請求流轉到Wrapper後,會進入它的pipeline組件中,並且經過內部Valve的過濾,Wrapper內部的WrapperValve創建FilterChain實例,調用指定的Servlet實例處理請求
  • 最後將請求結果返回
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章