生活随笔
收集整理的這篇文章主要介紹了
Tomcat源码解析系列二:Tomcat总体架构
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Tomcat即是一個(gè)HTTP服務(wù)器,也是一個(gè)servlet容器,主要目的就是包裝servlet,并對(duì)請(qǐng)求響應(yīng)相應(yīng)的servlet,純servlet的web應(yīng)用似乎很好理解Tomcat是如何裝載servlet的,但,當(dāng)使用一些MVC框架時(shí),如spring MVC、strusts2,可能就找不出servlet在哪里?其實(shí)spring MVC框架就是一整個(gè)servlet,在web.xml中配置如下:
[html]?view plaincopy
??????<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:spring-mvc.xml</param-value>??????????</init-param>??????????<load-on-startup>1</load-on-startup>??????????<async-supported>true</async-supported>??????</servlet>??????<servlet-mapping>??????????<servlet-name>SpringMVC</servlet-name>????????????????????<url-pattern>/</url-pattern>??????</servlet-mapping>??
而Struts2是基于過濾器的(過濾器也稱作閥門,過濾器鏈相當(dāng)于流水線),過濾器執(zhí)行在調(diào)用servlet的service()方法之前。在web.xml的配置如下:
[html]?view plaincopy
<span?style="font-family:Comic?Sans?MS;font-size:18px;"><filter>??????<filter-name>struts2</filter-name>??????<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>????</filter>????<filter-mapping>??????<filter-name>struts2</filter-name>??????<url-pattern>/*</url-pattern>????</filter-mapping></span>??
他的總體結(jié)構(gòu)用下圖來表示。
? ?通過上圖我們可以看出Tomcat中主要涉及Server,Service,Engine,Connector,Host,Context組件,之前用過Tomcat的童鞋是不是覺得這些組件的名稱有點(diǎn)似曾相識(shí)的趕腳,沒趕腳?!您再想想。好吧,不用你想了,我來告訴你吧。其實(shí)在Tomcat二進(jìn)制分發(fā)包解壓后,在conf目錄中有一個(gè)server.xml文件,你打開它瞄兩眼看看,是不是發(fā)現(xiàn)server.xml文件中已經(jīng)包含了上述的幾個(gè)名稱。
[html]?view plaincopy
<?xml?version='1.0'?encoding='utf-8'?>??<!--????Licensed?to?the?Apache?Software?Foundation?(ASF)?under?one?or?more????contributor?license?agreements.??See?the?NOTICE?file?distributed?with????this?work?for?additional?information?regarding?copyright?ownership.????The?ASF?licenses?this?file?to?You?under?the?Apache?License,?Version?2.0????(the?"License");?you?may?not?use?this?file?except?in?compliance?with????the?License.??You?may?obtain?a?copy?of?the?License?at??????????http://www.apache.org/licenses/LICENSE-2.0??????Unless?required?by?applicable?law?or?agreed?to?in?writing,?software????distributed?under?the?License?is?distributed?on?an?"AS?IS"?BASIS,????WITHOUT?WARRANTIES?OR?CONDITIONS?OF?ANY?KIND,?either?express?or?implied.????See?the?License?for?the?specific?language?governing?permissions?and????limitations?under?the?License.??-->??<!--?Note:??A?"Server"?is?not?itself?a?"Container",?so?you?may?not???????define?subcomponents?such?as?"Valves"?at?this?level.???????Documentation?at?/docs/config/server.html???-->??<Server?port="8005"?shutdown="SHUTDOWN">????<!--?Security?listener.?Documentation?at?/docs/config/listeners.html????<Listener?className="org.apache.catalina.security.SecurityListener"?/>????-->????????<Listener?className="org.apache.catalina.core.AprLifecycleListener"?SSLEngine="on"?/>????????<Listener?className="org.apache.catalina.core.JasperListener"?/>????????<Listener?className="org.apache.catalina.core.JreMemoryLeakPreventionListener"?/>????<Listener?className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"?/>????<Listener?className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"?/>??????<!--?Global?JNDI?resources?????????Documentation?at?/docs/jndi-resources-howto.html????-->????<GlobalNamingResources>??????<!--?Editable?user?database?that?can?also?be?used?by???????????UserDatabaseRealm?to?authenticate?users??????-->??????<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>??????<!--?A?"Service"?is?a?collection?of?one?or?more?"Connectors"?that?share?????????a?single?"Container"?Note:??A?"Service"?is?not?itself?a?"Container",?????????so?you?may?not?define?subcomponents?such?as?"Valves"?at?this?level.?????????Documentation?at?/docs/config/service.html?????-->????<Service?name="Catalina">??????????????<!--??????<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?(blocking?&?non-blocking)???????????Java?AJP??Connector:?/docs/config/ajp.html???????????APR?(HTTP/AJP)?Connector:?/docs/apr.html???????????Define?a?non-SSL?HTTP/1.1?Connector?on?port?8080??????-->??????<Connector?port="8080"?protocol="HTTP/1.1"?????????????????connectionTimeout="20000"?????????????????redirectPort="8443"?/>????????????<!--??????<Connector?executor="tomcatThreadPool"?????????????????port="8080"?protocol="HTTP/1.1"?????????????????connectionTimeout="20000"?????????????????redirectPort="8443"?/>??????-->??????<!--?Define?a?SSL?HTTP/1.1?Connector?on?port?8443???????????This?connector?uses?the?JSSE?configuration,?when?using?APR,?the???????????connector?should?be?using?the?OpenSSL?style?configuration???????????described?in?the?APR?documentation?-->??????<!--??????<Connector?port="8443"?protocol="HTTP/1.1"?SSLEnabled="true"?????????????????maxThreads="150"?scheme="https"?secure="true"?????????????????clientAuth="false"?sslProtocol="TLS"?/>??????-->??????????????<Connector?port="8009"?protocol="AJP/1.3"?redirectPort="8443"?/>??????????<!--?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="192.168.1.50"?jvmRoute="jvm1">??????-->??????<Engine?name="Catalina"?defaultHost="192.168.1.50">??????????<!--For?clustering,?please?take?a?look?at?documentation?at:????????????/docs/cluster-howto.html??(simple?how?to)????????????/docs/config/cluster.html?(reference?documentation)?-->????????????????????<!--?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?name="192.168.1.50"??appBase="webapps"??????????????unpackWARs="true"?autoDeploy="true">????????????<!--?SingleSignOn?valve,?share?authentication?between?web?applications???????????????Documentation?at:?/docs/config/valve.html?-->????????????????????????<!--?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="192.168.1.50_access_log."?suffix=".txt"?????????????????pattern="%h?%l?%u?%t?"%r"?%s?%b"?/>??????????</Host>??????</Engine>????</Service>??</Server>??
? ? Tomcat加載時(shí)相應(yīng)組件(容器)的配置參數(shù)都是從這個(gè)文件讀進(jìn)去的,這個(gè)文件也是Tomcat性能優(yōu)化的關(guān)鍵。
接下來我們就根據(jù)上圖以及conf/server.xml的內(nèi)容來一步步描述一下上面所說的各種組件吧。
Server
Server是Tomcat中最頂層的組件,它可以包含多個(gè)Service組件。在Tomcat源代碼中Server組件對(duì)應(yīng)源碼中的 ?org.apache.catalina.core.StandardServer?
類。StandardServer的繼承關(guān)系圖如下圖所示:
Lifecycle是Tomcat的生命周期接口。保持組件啟動(dòng)和停止一致的的機(jī)制通過實(shí)現(xiàn)org.apache.catalina.Lifecycle接口來實(shí)現(xiàn)。
Service
接下來咋們來看看Service組件,Service組件相當(dāng)于Connetor和Engine組件的包裝器,它將一個(gè)或者多個(gè)Connector組件和一個(gè)Engine建立關(guān)聯(lián)。上述配置文件中,定義一個(gè)叫
Catalina
的服務(wù),并將Http,AJP(定向包的協(xié)議)這兩個(gè)Connector關(guān)聯(lián)到了一個(gè)名為
Catalina
的Service,注意一個(gè)Connetor對(duì)應(yīng)處理一種協(xié)議。Service組件對(duì)應(yīng)Tomcat源代碼中的
org.apache.catalina.core.StandardService
,StandardService的繼承關(guān)系圖如下圖所示:
Connector
既然Tomcat需要提供http服務(wù),而我們知道http應(yīng)用層協(xié)議最終都是需要通過TCP層的協(xié)議進(jìn)行傳遞的,而Connector正是Tomcat中監(jiān)聽TCP網(wǎng)絡(luò)連接的組件,一個(gè)Connector會(huì)監(jiān)聽一個(gè)獨(dú)立的端口來處理來自客戶端的連接。缺省的情況下Tomcat提供了如下兩個(gè)Connector。我們分別描述一下:
HTTP/1.1
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />?上面定義了一個(gè)Connector,它缺省監(jiān)聽端口8080,這個(gè)端口我們可以根據(jù)具體情況進(jìn)行改動(dòng)。connectionTimeout定義了連接超時(shí)時(shí)間,單位是毫秒,redirectPort定義了ssl的重定向接口,根據(jù)缺省的配置,Connector會(huì)將ssl請(qǐng)求重定向到8443端口。AJP/1.3
AJP表示Apache Jserv Protocol,此連接器將處理Tomcat和Aapache http服務(wù)器之間的交互,這個(gè)連接器是用來處理我們將Tomcat和Apache http服務(wù)器結(jié)合使用的情況。假如在同樣的一臺(tái)物理Server上面部署了一臺(tái)Apache http服務(wù)器和多臺(tái)Tomcat服務(wù)器,通過Apache服務(wù)器來處理靜態(tài)資源以及負(fù)載均衡的時(shí)候,針對(duì)不同的Tomcat實(shí)例需要AJP監(jiān)聽不同的端口。
Connector對(duì)應(yīng)源代碼中的
org.apache.catalina.connector.Connector
,它的繼承關(guān)系圖如下所示:
Engine
Tomcat中有一個(gè)容器的概念,而Engine,Host,Context都屬于Contanier,我們先來說說最頂層的容器Engine.
一個(gè)Engine可以包含一個(gè)或者多個(gè)Host,也就是說我們一個(gè)Tomcat的實(shí)例可以配置多個(gè)虛擬主機(jī)。
缺省的情況下<Engine name="Catalina" defaultHost="localhost">定義了一個(gè)名稱為Cataline的Engine.Engine對(duì)應(yīng)源代碼中的org.apache.catalina.core.StandardEngine,它的繼承關(guān)系圖如下圖所示:
Host定義了一個(gè)虛擬主機(jī),一個(gè)虛擬主機(jī)可以有多個(gè)Context,缺省的配置如下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">….</Host>?其中appBase為webapps,也就是<CATALINA_HOME>\webapps目錄,unpackingWARS屬性指定在appBase指定的目錄中的war包都自動(dòng)的解壓,缺省配置為true,autoDeploy屬性指定是否對(duì)加入到appBase目錄的war包進(jìn)行自動(dòng)的部署,缺省為true.
Host對(duì)應(yīng)源代碼中的org.apache.catalina.core.StandardHost,它的繼承關(guān)系圖如下所示:
Context
在Tomcat中,每一個(gè)運(yùn)行的webapp其實(shí)最終都是以Context的形成存在,每個(gè)Context都有一個(gè)根路徑和請(qǐng)求URL路徑,Context對(duì)應(yīng)源代碼中的org.apache.catalina.core.StandardContext,它的繼承關(guān)系圖如下圖所示:
在Tomcat中我們通常采用如下的兩種方式創(chuàng)建一個(gè)Context.下面分別描述一下:
在<CATALINA-HOME>\webapps目錄中創(chuàng)建一個(gè)目錄,這個(gè)時(shí)候?qū)⒆詣?dòng)創(chuàng)建一個(gè)context,默認(rèn)context的訪問url為http://host:port/dirname,你也可以通過在ContextRoot\META-INF中創(chuàng)建一個(gè)context.xml的文件,其中包含如下的內(nèi)容來指定應(yīng)用的訪問路徑。?<Context path="/yourUrlPath" />conf\server.xml文件中增加context元素。 第二種創(chuàng)建context的方法,我們可以選擇在server.xml文件的<Host>元素,比如我們?cè)趕erver.xml文件中增加如下內(nèi)容:
[html]?view plaincopy
?.......??
[html]?view plaincopy
<span?style="line-height:?1.5;">??</span><span?style="line-height:?1.5;">.........</span>??
[html]?view plaincopy
????<Context?path="/mypath"?docBase="/Users/xxx"?reloadable="true">????????</Context>??</Host>??t;/Engine>??</Service>??t;/Server>??
這樣的話,我們就可以通過
http://host:port/mypath
訪問上面配置的context了。
Valve
Valve中文意思是閥門,Valve是Tomcat中責(zé)任鏈模式的實(shí)現(xiàn),通過鏈接多個(gè)Valve對(duì)請(qǐng)求進(jìn)行處理。每個(gè)容器都有一個(gè)流水線Pipeline(過濾器鏈),每個(gè)流水線至少有一個(gè)閥門。其中Valve可以定義在任何的Container中,上面說的Engine,Host,Context都屬于容器。tomcat 默認(rèn)定義了一個(gè)名為org.apache.catalina.valves.AccessLogValve的Valve,這個(gè)Valve負(fù)責(zé)攔截每個(gè)請(qǐng)求,然后記錄一條訪問日志。
通過上面的分析,我們發(fā)現(xiàn)Server,Service,Engine,Host,Context都實(shí)現(xiàn)了org.apache.catalina.Lifecycle接口,通過這個(gè)接口管理了這些核心組件的生命周期,關(guān)于這些組件的生命周期,我們?cè)谙乱黄恼旅枋觥?/p>
Tomcat總體架構(gòu)(Tomcat源碼解析系列二)
總結(jié)
以上是生活随笔為你收集整理的Tomcat源码解析系列二:Tomcat总体架构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。