<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    飛艷小屋

    程序--人生--哲學___________________歡迎艷兒的加入

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      52 Posts :: 175 Stories :: 107 Comments :: 0 Trackbacks

    TOMCAT源碼分析(啟動框架)
    前言:
    ???本文是我閱讀了TOMCAT源碼后的一些心得。?主要是講解TOMCAT的系統框架,?以及啟動流程。若有錯漏之處,敬請批評指教!
    建議:
    ???畢竟TOMCAT的框架還是比較復雜的,?單是從文字上理解,?是不那么容易掌握TOMCAT的框架的。?所以得實踐、實踐、再實踐。?建議下載一份TOMCAT的源碼,?調試通過,?然后單步跟蹤其啟動過程。?如果有不明白的地方,?再來查閱本文,?看是否能得到幫助。?我相信這樣效果以及學習速度都會好很多!
    ???
    1.?Tomcat的整體框架結構
    ???Tomcat的基本框架,?分為4個層次。
    ???Top?Level?Elements:
    ????Server
    ????Service???
    ???Connector
    ????HTTP
    ????AJP
    ???Container
    ???Engine
    ?????Host
    ???Context
    ???Component??
    ????manager
    ???logger
    ???loader
    ???pipeline
    ???valve
    ?????????...
    ???站在框架的頂層的是Server和Service
    ???Server:??其實就是BackGroud程序,?在Tomcat里面的Server的用處是啟動和監聽服務端事件(諸如重啟、關閉等命令。? 在tomcat的標準配置文件:server.xml里面,?我們可以看到“<Server?port="8005"?shutdown= "SHUTDOWN"?debug="0">”這里的"SHUTDOWN"就是server在監聽服務端事件的時候所使用的命令字)
    ???Service:?在tomcat里面,?service是指一類問題的解決方案。??通常我們會默認使用tomcat提供的:Tomcat- Standalone?模式的service。?在這種方式下的service既給我們提供解析jsp和servlet的服務,?同時也提供給我們解析靜態文本的服務。
    ???
    ???Connector:?Tomcat都是在容器里面處理問題的,?而容器又到哪里去取得輸入信息呢?
    Connector就是專干這個的。?他會把從socket傳遞過來的數據,?封裝成Request,?傳遞給容器來處理。
    ???通常我們會用到兩種Connector,一種叫http?connectoer,?用來傳遞http需求的。?另一種叫AJP,?在我們整合 apache與tomcat工作的時候,?apache與tomcat之間就是通過這個協議來互動的。?(說到apache與tomcat的整合工作,? 通常我們的目的是為了讓apache?獲取靜態資源,?而讓tomcat來解析動態的jsp或者servlet。)
    ???Container:?當http?connector把需求傳遞給頂級的container:?Engin的時候,?我們的視線就應該移動到Container這個層面來了。
    ???在Container這個層,?我們包含了3種容器:?Engin,?Host,?Context.
    ???Engin:?收到service傳遞過來的需求,?處理后,?將結果返回給service(?service?是通過?connector?這個媒介來和Engin互動的?).
    ???Host:?Engin收到service傳遞過來的需求后,不會自己處理,?而是交給合適的Host來處理。
    Host在這里就是虛擬主機的意思,?通常我們都只會使用一個主機,既“localhost”本地機來處理。?
    ???Context:?Host接到了從Host傳過來的需求后,?也不會自己處理,?而是交給合適的Context來處理。?
    ???比如:?<http://127.0.0.1:8080/foo/index.jsp>
    ?????????<http://127.0.1:8080/bar/index.jsp>
    ???前者交給foo這個Context來處理,?后者交給bar這個Context來處理。
    ???很明顯吧!?context的意思其實就是一個web?app的意思。
    ???我們通常都會在server.xml里面做這樣的配置
    ???<Context?path="/foo"?docBase="D:/project/foo/web"?/>
    ???這個context容器,就是用來干我們該干的事兒的地方的。
    ???
    ???Compenent:?接下來,?我們繼續講講component是干什么用的。
    ???我們得先理解一下容器和組件的關系。
    ???需求被傳遞到了容器里面,?在合適的時候,?會傳遞給下一個容器處理。
    ???而容器里面又盛裝著各種各樣的組件,?我們可以理解為提供各種各樣的增值服務。
    ???manager:?當一個容器里面裝了manager組件后,這個容器就支持session管理了,?事實上在tomcat里面的session管理,?就是靠的在context里面裝的manager?component.
    ???logger:?當一個容器里面裝了logger組件后,?這個容器里所發生的事情,?就被該組件記錄下來啦!?我們通常會在logs/?這個目錄下看見?catalina_log.time.txt?以及?localhost.time.txt?和 localhost_examples_log.time.txt。?這就是因為我們分別為:engin,?host以及context (examples)這三個容器安裝了logger組件,?這也是默認安裝,?又叫做標配?:)
    ???loader:?loader這個組件通常只會給我們的context容器使用,?loader是用來啟動context以及管理這個context的classloader用的。
    ????pipline:?pipeline是這樣一個東西,?當一個容器決定了要把從上級傳遞過來的需求交給子容器的時候,?他就把這個需求放進容器的管道(pipeline)里面去。?而需求傻呼呼得在管道里面流動的時候,?就會被管道里面的各個閥門攔截下來。?比如管道里面放了兩個閥門。?第一個閥門叫做“access_allow_vavle”,?也就是說需求流過來的時候,它會看這個需求是哪個IP過來的,?如果這個IP已經在黑名單里面了, ?sure,?殺!?第二個閥門叫做“defaul_access_valve”它會做例行的檢查,?如果通過的話,OK,?把需求傳遞給當前容器的子容器。?就是通過這種方式,?需求就在各個容器里面傳遞,流動,?最后抵達目的地的了。
    ????valve:?就是上面所說的閥門啦。
    ???Tomcat里面大概就是這么些東西,?我們可以簡單地這么理解tomcat的框架,它是一種自上而下,?容器里又包含子容器的這樣一種結構。
    2.?Tomcat的啟動流程
    ???這篇文章是講tomcat怎么啟動的,既然我們大體上了解了TOMCAT的框架結構了,?那么我們可以望文生意地就猜到tomcat的啟動,?會先啟動父容器,然后逐個啟動里面的子容器。?啟動每一個容器的時候,?都會啟動安插在他身上的組件。?當所有的組件啟動完畢,?所有的容器啟動完畢的時候, ?tomcat本身也就啟動完畢了。
    ???順理成章地,?我們同樣可以猜到,?tomcat的啟動會分成兩大部分,?第一步是裝配工作。?第二步是啟動工作。?
    ???裝配工作就是為父容器裝上子容器,?為各個容器安插進組件的工作。?這個地方我們會用到digester模式,?至于digester模式什么,?有什么用,?怎么工作的.?請參考?<http://software.ccidnet.com/pub/article/c322_a31671_p2.html>
    ???啟動工作是在裝配工作之后,?一旦裝配成功了,?我們就只需要點燃最上面的一根導線,?整個tomcat就會被激活起來。?這就好比我們要開一輛已經裝配好了的汽車的時候一樣,我們只要把鑰匙插進鑰匙孔,一擰,汽車的引擎就會發動起來,空調就會開起來,?安全裝置就會生效,?如此一來,汽車整個就發動起來了。(這個過程確實和TOMCAT的啟動過程不謀而和,?讓我們不得不懷疑?TOMCAT的設計者是在GE做JAVA開發的)。
    2.1?一些有意思的名稱:
    ???Catalina
    ???Tomcat
    ???Bootstrap
    ???Engin
    ???Host
    ???Context
    ???他們的意思很有意思:
    ???Catalina:?遠程轟炸機
    ???Tomcat:?熊貓轟炸機?--?轟炸機的一種(這讓我想起了讓國人引以為豪的熊貓手機,是不是英文可以叫做tomcat????,?又讓我想起了另一則廣告:?波導-手機中的戰斗機、波音-客機中的戰斗機?)
    ???Bootstap:?引導
    ???Engin:?發動機
    ???Host:?主機,領土
    ???Context:?內容,?目標,?上下文
    ???
    ???...?在許多許多年后,?現代人類已經滅絕。?后現代生物發現了這些單詞零落零落在一塊。?一個自以為聰明的家伙把這些東西翻譯出來了:?
    ???在地勤人員的引導(bootstrap)下,?一架轟炸架(catalina)騰空躍起,?遠看是熊貓轟炸機(tomcat),?近看還是熊貓轟炸機!?憑借著優秀的發動機技術(engin),?這架熊貓轟炸機飛臨了敵國的領土上空(host),?對準目標(context)投下了毀天滅地的核彈頭,波~?現代生物就這么隔屁了~
    ?
    ???綜上所述,?這又不得不讓人聯想到GE是不是也參與了軍事設備的生產呢?
    ???反對美帝國主義!?反對美霸權主義!?和平萬歲!?自由萬歲!
    ???
    2.2??歷史就是那么驚人的相似!?tomcat的啟動就是從org.apache.catalina.startup.Bootstrap這個類悍然啟動的!
    ???在Bootstrap里做了兩件事:
    ???1.?指定了3種類型classloader:
    ??????commonLoader:?common/classes、common/lib、common/endorsed
    ??????catalinaLoader:?server/classes、server/lib、commonLoader
    ??????sharedLoader:??shared/classes、shared/lib、commonLoader
    ???2.?引導Catalina的啟動。
    ??????用Reflection技術調用org.apache.catalina.startup.Catalina的process方法,?并傳遞參數過去。
    ???
    2.3?Catalina.java
    ???Catalina完成了幾個重要的任務:
    ???1.?使用Digester技術裝配tomcat各個容器與組件。
    ??????1.1?裝配工作的主要內容是安裝各個大件。?比如server下有什么樣的servcie。?Host會容納多少個context。?Context都會使用到哪些組件等等。?
    ??????1.2?同時呢,?在裝配工作這一步,?還完成了mbeans的配置工作。?在這里,我簡單地但不十分精確地描述一下mbean是什么,干什么用的。
    ??????????我們自己生成的對象,?自己管理,?天經地義!?但是如果我們創建了對象了,?想讓別人來管,?怎么辦呢??我想至少得告訴別人我們都有什么,?以及通過什么方法可以找到??吧!?JMX技術給我們提供了一種手段。?JMX里面主要有3種東西。Mbean,?agent, ?connector.
    ???????Mbean:?用來映射我們的對象。也許mbean就是我們創建的對象,?也許不是,?但有了它,?就可以引用到我們的對象了。
    ???????Agent:??通過它,?就可以找到mbean了。
    ???????Connector:?連接Agent的方式。?可以是http的,?也可以是rmi的,還可以直接通過socket。
    ??????發生在tomcat?裝配過程中的事情:??GlobalResourcesLifecycleListener?類的初始化會被觸發:
    ?????????protected?static?Registry?registry?=?MBeanUtils.createRegistry();??會運行
    ?????????MBeanUtils.createRegistry()??會依據 /org/apache/catalina/mbeans/mbeans-descriptors.xml這個配置文件創建?mbeans.?Ok,?外界就有了條途徑訪問tomcat中的各個組件了。(有點像后門兒)
    ???2.?為top?level?的server?做初始化工作。?實際上就是做通常會配置給service的兩條connector.(http,?ajp)
    ???3.?從server這個容器開始啟動,?點燃整個tomcat.
    ???4.?為server做一個hook程序,?檢測當server?shutdown的時候,?關閉tomcat的各個容器用。
    ???5.?監聽8005端口,?如果發送"SHUTDOWN"(默認培植下字符串)過來,?關閉8005serverSocket。
    2.4?啟動各個容器
    ???1.?Server
    ??????觸發Server容器啟動前(before_start),?啟動中(start),?啟動后(after_start)3個事件,?并運行相應的事件處理器。
    ??????啟動Server的子容器:Servcie.?
    ???2.?Service
    ??????啟動Service的子容器:Engin
    ??????啟動Connector
    ???3.?Engin
    ??????到了Engin這個層次,以及以下級別的容器,?Tomcat就使用了比較一致的啟動方式了。
    ??????首先,??運行各個容器自己特有一些任務
    ??????隨后,??觸發啟動前事件
    ??????立即,??設置標簽,就表示該容器已經啟動
    ??????接著,??啟動容器中的各個組件:?loader,?logger,?manager等等
    ??????再接著,啟動mapping組件。(注1)
    ??????緊跟著,啟動子容器。
    ??????接下來,啟動該容器的管道(pipline)
    ??????然后,??觸發啟動中事件
    ??????最后,??觸發啟動后事件。
    ?
    ??????Engin大致會這么做,?Host大致也會這么做,?Context大致還是會這么做。?那么很顯然地,?我們需要在這里使用到代碼復用的技術。?tomcat在處理這個問題的時候,?漂亮地使用了抽象類來處理。?ContainerBase.?最后使得這部分完成復雜功能的代碼顯得干凈利落,?干練爽快,?實在是令人覺得嘆為觀止,?細細品來,?直覺如享佳珍,?另人齒頰留香,?留戀往返啊!
    ??????
    ??????Engin的觸發啟動前事件里,?會激活綁定在Engin上的唯一一個Listener:EnginConfig。
    ??????這個EnginConfig類基本上沒有做什么事情,?就是把EnginConfig的調試級別設置為和Engin相當。?另外就是輸出幾行文本,?表示Engin已經配置完畢,?并沒有做什么實質性的工作。
    ??????注1:?mapping組件的用處是,?當一個需求將要從父容器傳遞到子容器的時候,?而父容器又有多個子容器的話,?那么應該選擇哪個子容器來處理需求呢??這個由mapping?組件來定奪。
    ????
    ???4.?Host
    ???????同Engin一樣,?也是調用ContainerBase里面的start()方法,?不過之前做了些自個兒的任務,就是往Host這個容器的通道(pipline)里面,?安裝了一個叫做
    ?“org.apache.catalina.valves.ErrorReportValve”的閥門。
    ???????這個閥門的用處是這樣的:??需求在被Engin傳遞給Host后,?會繼續傳遞給Context做具體的處理。?這里需求其實就是作為參數傳遞的Request,?Response。?所以在context把需求處理完后,?通常會改動response。?而這個 org.apache.catalina.valves.ErrorReportValve的作用就是檢察response是否包含錯誤,?如果有就做相應的處理。
    ???5.?Context
    ???????到了這里,?就終于輪到了tomcat啟動中真正的重頭戲,啟動Context了。
    ?StandardContext.start()?這個啟動Context容器的方法被StandardHost調用.
    ?5.1?webappResources?該context所指向的具體目錄
    ?5.2?安裝defaultContex,?DefaultContext?就是默認Context。?如果我們在一個Host下面安裝了 DefaultContext,而且defaultContext里面又安裝了一個數據庫連接池資源的話。?那么其他所有的在該Host下的 Context,?都可以直接使用這個數據庫連接池,?而不用格外做配置了。
    ??5.3?指定Loader.?通常用默認的org.apache.catalina.loader.WebappLoader這個類。???Loader就是用來指定這個context會用到哪些類啊,?哪些jar包啊這些什么的。
    ?5.4?指定?Manager.?通常使用默認的org.apache.catalina.session.?StandardManager?。?Manager是用來管理session的。
    ?????其實session的管理也很好實現。?以一種簡單的session管理為例。?當需求傳遞過來的時候,?在Request對象里面有一個 sessionId?屬性。?OK,?得到這個sessionId后,?我們就可以把它作為map的key,而value我們可以放置一個 HashMap.?HashMap里邊兒,?再放我們想放的東西。
    ?5.5?postWorkDirectory?().?Tomcat下面有一個work目錄。?我們把臨時文件都扔在那兒去。?這個步驟就是在那里創建一個目錄。?一般說來會在%CATALINA_HOME%/work/Standalone\localhost\?這個地方生成一個目錄。
    5.6??Binding?thread。到了這里,?就應該發生?class?Loader?互換了。?之前是看得見tomcat下面所有的class 和lib.?接下來需要看得見當前context下的class。?所以要設置contextClassLoader,?同時還要把舊的 ClassLoader記錄下來,因為以后還要用的。
    5.7??啟動?Loader.?指定這個Context具體要使用哪些classes,?用到哪些jar文件。?如果reloadable設置成了true,?就會啟動一個線程來監視classes的變化,?如果有變化就重新啟動Context。
    5.8??啟動logger
    5.9??觸發安裝在它身上的一個監聽器。
    ?lifecycle.fireLifecycleEvent(START_EVENT,?null);?
    ?作為監聽器之一,ContextConfig會被啟動.?ContextConfig就是用來配置web.xml的。?比如這個Context有多少Servlet,?又有多少Filter,?就是在這里給Context裝上去的。
    ?5.9.1?defaultConfig.?每個context都得配置?tomcat/conf/web.xml?這個文件。
    ?5.9.2?applicationConfig?配置自己的?WEB-INF/web.xml?文件
    5.9.3?validateSecurityRoles?權限驗證。?通常我們在訪問/admin?或者/manager的時候,需要用戶要么是 admin的要么是manager的,?才能訪問。?而且我們還可以限制那些資源可以訪問,?而哪些不能。?都是在這里實現的。
    5.9.4?tldScan:?掃描一下,?需要用到哪些標簽(tag?lab)
    5.10?啟動?manager
    5.11?postWelcomeFiles()?我們通常會用到的3個啟動文件的名稱:
    index.html、index.htm、index.jsp?就被默認地綁在了這個context上
    ?5.12?listenerStart?配置listener
    ?5.13?filterStart?配置?filter
    ?5.14?啟動帶有<load-on-startup>1</load-on-startup>的Servlet.
    ??順序是從小到大:?1,2,3…?最后是0
    ??默認情況下,?至少會啟動如下3個的Servlet:?
    ??org.apache.catalina.servlets.DefaultServlet???
    ??????處理靜態資源的Servlet.?什么圖片啊,?html啊,?css啊,?js啊都找他
    ??org.apache.catalina.servlets.InvokerServlet
    ??????處理沒有做Servlet?Mapping的那些Servlet.
    ??org.apache.jasper.servlet.JspServlet?
    ??????處理JSP文件的.
    ???????5.15??標識context已經啟動完畢。
    ?走了多少個步驟啊,?Context總算是啟動完畢嘍。
    ????OK!?走到了這里,?每個容器以及組件都啟動完畢。?Tomcat終于不辭辛勞地為人民服務了!
    3.?參考文獻:
    ????<http://jakarta.apache.org/tomcat/>
    ????<http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html>
    ????
    4.?后記
    ????這篇文章是講解tomcat啟動框架的,還有篇文章是講解TOMCAT里面的消息處理流程的細節的。?文章內容已經寫好了,?現在正在整理階段。?相信很快就可以做出來,?大家共同研究共同進步。
    ????這篇文章是獨自分析TOMCAT源碼所寫的,?所以一定有地方是帶有個人主觀色彩,?難免會有片面之處。若有不當之處敬請批評指教,這樣不僅可以使剛開始研究TOMCAT的兄弟們少走彎路,?我也可以學到東西。
    ????email:?sojan_java@yahoo.com.cn

    5.?tomcat源碼分析(消息處理)

    posted on 2007-03-21 13:07 天外飛仙 閱讀(1009) 評論(0)  編輯  收藏 所屬分類: java服務器相關
    主站蜘蛛池模板: 午夜dj在线观看免费视频| 91成年人免费视频| 亚洲中文字幕不卡无码| 一级毛片试看60分钟免费播放| 男女啪啪永久免费观看网站| 456亚洲人成影院在线观| 性生交片免费无码看人| 亚洲人成网国产最新在线| 性感美女视频在线观看免费精品| 亚洲最大av资源站无码av网址| 天天天欲色欲色WWW免费| 国产亚洲欧美在线观看| 免费人成网站在线高清| yellow免费网站| 无码久久精品国产亚洲Av影片| 69av免费观看| 亚洲人成欧美中文字幕| 亚洲一区二区精品视频| 精品国产麻豆免费人成网站| 亚洲精品综合久久中文字幕 | 一级毛片免费毛片毛片| 亚洲人成色77777在线观看大| 中文在线观看免费网站| 99久久亚洲综合精品成人网| 好先生在线观看免费播放| 亚洲av永久无码| 亚洲精品国偷自产在线| 麻豆视频免费播放| 羞羞视频网站免费入口| 国产∨亚洲V天堂无码久久久| 男女做羞羞的事视频免费观看无遮挡 | 亚洲国产精品无码久久一区二区| 一级毛片免费毛片一级毛片免费| 亚洲免费一级视频| 亚洲最大av无码网址| 91麻豆国产免费观看| 瑟瑟网站免费网站入口| 99ri精品国产亚洲| 免费在线观看中文字幕| 91福利视频免费| 日本一区二区三区免费高清在线|