1 - Tomcat Server的組成部分
1.1 - Server
A Server element represents the entire Catalina servlet container. (Singleton)
1.2 - Service
A Service element represents the combination of one or more Connector components that share a single Engine
Service是這樣一個(gè)集合:它由一個(gè)或者多個(gè)Connector組成,以及一個(gè)Engine,負(fù)責(zé)處理所有Connector所獲得的客戶請(qǐng)求
1.3 - Connector
一個(gè)Connector將在某個(gè)指定端口上偵聽客戶請(qǐng)求,并將獲得的請(qǐng)求交給Engine來處理,從Engine處獲得回應(yīng)并返回客戶
TOMCAT有兩個(gè)典型的Connector,一個(gè)直接偵聽來自browser的http請(qǐng)求,一個(gè)偵聽來自其它WebServer的請(qǐng)求
Coyote Http/1.1 Connector 在端口8080處偵聽來自客戶browser的http請(qǐng)求
Coyote JK2 Connector 在端口8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請(qǐng)求
1.4 - Engine
The Engine element represents the entire request processing machinery associated with a particular Service
It receives and processes all requests from one or more Connectors
and returns the completed response to the Connector for ultimate transmission back to the client
Engine下可以配置多個(gè)虛擬主機(jī)Virtual Host,每個(gè)虛擬主機(jī)都有一個(gè)域名
當(dāng)Engine獲得一個(gè)請(qǐng)求時(shí),它把該請(qǐng)求匹配到某個(gè)Host上,然后把該請(qǐng)求交給該Host來處理
Engine有一個(gè)默認(rèn)虛擬主機(jī),當(dāng)請(qǐng)求無法匹配到任何一個(gè)Host上的時(shí)候,將交給該默認(rèn)Host來處理
1.5 - Host
?
代表一個(gè)Virtual Host,虛擬主機(jī),每個(gè)虛擬主機(jī)和某個(gè)網(wǎng)絡(luò)域名Domain Name相匹配
每個(gè)虛擬主機(jī)下都可以部署(deploy)一個(gè)或者多個(gè)Web App,每個(gè)Web App對(duì)應(yīng)于一個(gè)Context,有一個(gè)Context path
當(dāng)Host獲得一個(gè)請(qǐng)求時(shí),將把該請(qǐng)求匹配到某個(gè)Context上,然后把該請(qǐng)求交給該Context來處理
匹配的方法是“最長匹配”,所以一個(gè)path==""的Context將成為該Host的默認(rèn)Context
所有無法和其它Context的路徑名匹配的請(qǐng)求都將最終和該默認(rèn)Context匹配
1.6 - Context
一個(gè)Context對(duì)應(yīng)于一個(gè)Web Application,一個(gè)Web Application由一個(gè)或者多個(gè)Servlet組成
Context在創(chuàng)建的時(shí)候?qū)⒏鶕?jù)配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml載入Servlet類
當(dāng)Context獲得請(qǐng)求時(shí),將在自己的映射表(mapping table)中尋找相匹配的Servlet類
如果找到,則執(zhí)行該類,獲得請(qǐng)求的回應(yīng),并返回
2 - Tomcat Server的結(jié)構(gòu)圖


3 - 配置文件$CATALINA_HOME/conf/server.xml的說明
該文件描述了如何啟動(dòng)Tomcat Server
?
4 - Context的部署配置文件web.xml的說明
一個(gè)Context對(duì)應(yīng)于一個(gè)Web App,每個(gè)Web App是由一個(gè)或者多個(gè)servlet組成的
當(dāng)一個(gè)Web App被初始化的時(shí)候,它將用自己的ClassLoader對(duì)象載入“部署配置文件web.xml”中定義的每個(gè)servlet類
它首先載入在$CATALINA_HOME/conf/web.xml中部署的servlet類
然后載入在自己的Web App根目錄下的WEB-INF/web.xml中部署的servlet類
web.xml文件有兩部分:servlet類定義和servlet映射定義
每個(gè)被載入的servlet類都有一個(gè)名字,且被填入該Context的映射表(mapping table)中,和某種URL PATTERN對(duì)應(yīng)
當(dāng)該Context獲得請(qǐng)求時(shí),將查詢mapping table,找到被請(qǐng)求的servlet,并執(zhí)行以獲得請(qǐng)求回應(yīng)
分析一下所有的Context共享的web.xml文件,在其中定義的servlet被所有的Web App載入
?
5 - Tomcat Server處理一個(gè)http請(qǐng)求的過程
假設(shè)來自客戶的請(qǐng)求為:
http://localhost:8080/wsota/wsota_index.jsp
2) Connector把該請(qǐng)求交給它所在的Service的Engine來處理,并等待來自Engine的回應(yīng)
3) Engine獲得請(qǐng)求localhost/wsota/wsota_index.jsp,匹配它所擁有的所有虛擬主機(jī)Host
4) Engine匹配到名為localhost的Host(即使匹配不到也把請(qǐng)求交給該Host處理,因?yàn)樵揌ost被定義為該Engine的默認(rèn)主機(jī))
5) localhost Host獲得請(qǐng)求/wsota/wsota_index.jsp,匹配它所擁有的所有Context
6) Host匹配到路徑為/wsota的Context(如果匹配不到就把該請(qǐng)求交給路徑名為""的Context去處理)
7) path="/wsota"的Context獲得請(qǐng)求/wsota_index.jsp,在它的mapping table中尋找對(duì)應(yīng)的servlet
8) Context匹配到URL PATTERN為*.jsp的servlet,對(duì)應(yīng)于JspServlet類
9) 構(gòu)造HttpServletRequest對(duì)象和HttpServletResponse對(duì)象,作為參數(shù)調(diào)用JspServlet的doGet或doPost方法
10)Context把執(zhí)行完了之后的HttpServletResponse對(duì)象返回給Host
11)Host把HttpServletResponse對(duì)象返回給Engine
12)Engine把HttpServletResponse對(duì)象返回給Connector
13)Connector把HttpServletResponse對(duì)象返回給客戶browser
<!----------------------------------------------------------------------------------------------->
<web-app>
<!-- 概述:
該文件是所有的WEB APP共用的部署配置文件,
每當(dāng)一個(gè)WEB APP被DEPLOY,該文件都將先被處理,然后才是WEB APP自己的/WEB-INF/web.xml
-->
<!-- +-------------------------+ -->
<!-- | servlet類定義部分 | -->
<!-- +-------------------------+ -->
<!-- DefaultServlet
當(dāng)用戶的HTTP請(qǐng)求無法匹配任何一個(gè)servlet的時(shí)候,該servlet被執(zhí)行
URL PATTERN MAPPING : /
-->
<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>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- InvokerServlet
處理一個(gè)WEB APP中的匿名servlet
當(dāng)一個(gè)servlet被編寫并編譯放入/WEB-INF/classes/中,卻沒有在/WEB-INF/web.xml中定義的時(shí)候
該servlet被調(diào)用,把匿名servlet映射成/servlet/ClassName的形式
URL PATTERN MAPPING : /servlet/*
-->
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- JspServlet
當(dāng)請(qǐng)求的是一個(gè)JSP頁面的時(shí)候(*.jsp)該servlet被調(diào)用
它是一個(gè)JSP編譯器,將請(qǐng)求的JSP頁面編譯成為servlet再執(zhí)行
URL PATTERN MAPPING : *.jsp
-->
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>WARNING</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>
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<!-- +------------------------+ -->
<!-- | 其它部分,略去先 | -->
<!-- +------------------------+ -->
... ... ... ...
</web-app>
<!----------------------------------------------------------------------------------------------->
<!----------------------------------------------------------------------------------------------->
<!-- 啟動(dòng)Server
在端口8005處等待關(guān)閉命令
如果接受到"SHUTDOWN"字符串則關(guān)閉服務(wù)器
-->
<Server port="8005" shutdown="SHUTDOWN" debug="0">
<!-- Listener ???
目前沒有看到這里
-->
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" debug="0"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" debug="0"/>
<!-- Global JNDI resources ???
目前沒有看到這里,先略去
-->
<GlobalNamingResources>
... ... ... ...
</GlobalNamingResources>
<!-- Tomcat的Standalone Service
Service是一組Connector的集合
它們共用一個(gè)Engine來處理所有Connector收到的請(qǐng)求
-->
<Service name="Tomcat-Standalone">
<!-- Coyote HTTP/1.1 Connector
className : 該Connector的實(shí)現(xiàn)類是org.apache.coyote.tomcat4.CoyoteConnector
port : 在端口號(hào)8080處偵聽來自客戶browser的HTTP1.1請(qǐng)求
minProcessors : 該Connector先創(chuàng)建5個(gè)線程等待客戶請(qǐng)求,每個(gè)請(qǐng)求由一個(gè)線程負(fù)責(zé)
maxProcessors : 當(dāng)現(xiàn)有的線程不夠服務(wù)客戶請(qǐng)求時(shí),若線程總數(shù)不足75個(gè),則創(chuàng)建新線程來處理請(qǐng)求
acceptCount : 當(dāng)現(xiàn)有線程已經(jīng)達(dá)到最大數(shù)75時(shí),為客戶請(qǐng)求排隊(duì)
當(dāng)隊(duì)列中請(qǐng)求數(shù)超過100時(shí),后來的請(qǐng)求返回Connection refused錯(cuò)誤
redirectport : 當(dāng)客戶請(qǐng)求是https時(shí),把該請(qǐng)求轉(zhuǎn)發(fā)到端口8443去
其它屬性略
-->
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8080"
minProcessors="5" maxProcessors="75" acceptCount="100"
enableLookups="true"
redirectPort="8443"
debug="0"
connectionTimeout="20000"
useURIValidationHack="false"
disableUploadTimeout="true" />
<!-- Engine用來處理Connector收到的Http請(qǐng)求
它將匹配請(qǐng)求和自己的虛擬主機(jī),并把請(qǐng)求轉(zhuǎn)交給對(duì)應(yīng)的Host來處理
默認(rèn)虛擬主機(jī)是localhost
-->
<Engine name="Standalone" defaultHost="localhost" debug="0">
<!-- 日志類,目前沒有看到,略去先 -->
<Logger className="org.apache.catalina.logger.FileLogger" .../>
<!-- Realm,目前沒有看到,略去先 -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" .../>
<!-- 虛擬主機(jī)localhost
appBase : 該虛擬主機(jī)的根目錄是webapps/
它將匹配請(qǐng)求和自己的Context的路徑,并把請(qǐng)求轉(zhuǎn)交給對(duì)應(yīng)的Context來處理
-->
<Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true">
<!-- 日志類,目前沒有看到,略去先 -->
<Logger className="org.apache.catalina.logger.FileLogger" .../>
<!-- Context,對(duì)應(yīng)于一個(gè)Web App
path : 該Context的路徑名是"",故該Context是該Host的默認(rèn)Context
docBase : 該Context的根目錄是webapps/mycontext/
-->
<Context path="" docBase="mycontext" debug="0"/>
<!-- 另外一個(gè)Context,路徑名是/wsota -->
<Context path="/wsota" docBase="wsotaProject" debug="0"/>
</Host>
</Engine>
</Service>
</Server>
<!----------------------------------------------------------------------------------------------->