前言 本文是我閱讀了TOMCAT源碼後的一些心得
主要是講解TOMCAT的系統框架
以及啟動流程
若有錯漏之處
敬請批評指教!
建議 畢竟TOMCAT的框架還是比較復雜的
單是從文字上理解
是不那麼容易掌握TOMCAT的框架的
所以得實踐
實踐
再實踐
建議下載一份TOMCAT的源碼
調試通過
然後單步跟蹤其啟動過程
如果有不明白的地方
再來查閱本文
看是否能得到幫助
我相信這樣效果以及學習速度都會好很多!
Tomcat的整體框架結構
Tomcat的基本框架
分為
個層次
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裡面
我們可以看到
這裡的SHUTDOWN就是server在監聽服務端事件的時候所使用的命令字)
Service 在tomcat裡面 service是指一類問題的解決方案 通常我們會默認使用tomcat提供的TomcatStandalone 模式的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這個層 我們包含了種容器 Engin Host Context
Engin: 收到service傳遞過來的需求 處理後 將結果返回給service( service 是通過 connector 這個媒介來和Engin互動的 )
Host: Engin收到service傳遞過來的需求後不會自己處理 而是交給合適的Host來處理
Host在這裡就是虛擬主機的意思 通常我們都只會使用一個主機既localhost本地機來處理
Context: Host接到了從Host傳過來的需求後 也不會自己處理 而是交給合適的Context來處理
比如 <>
<>
前者交給foo這個Context來處理 後者交給bar這個Context來處理
很明顯吧! context的意思其實就是一個web app的意思
我們通常都會在serverxml裡面做這樣的配置
這個context容器就是用來干我們該干的事兒的地方的
Compenent: 接下來 我們繼續講講component是干什麼用的
我們得先理解一下容器和組件的關系
需求被傳遞到了容器裡面 在合適的時候 會傳遞給下一個容器處理
而容器裡面又盛裝著各種各樣的組件 我們可以理解為提供各種各樣的增值服務
manager: 當一個容器裡面裝了manager組件後這個容器就支持session管理了 事實上在tomcat裡面的session管理 就是靠的在context裡面裝的manager component
logger: 當一個容器裡面裝了logger組件後 這個容器裡所發生的事情 就被該組件記錄下來啦! 我們通常會在logs/ 這個目錄下看見 catalina_logtimetxt 以及 localhosttimetxt 和localhost_examples_logtimetxt 這就是因為我們分別為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的框架它是一種自上而下 容器裡又包含子容器的這樣一種結構
Tomcat的啟動流程
這篇文章是講tomcat怎麼啟動的既然我們大體上了解了TOMCAT的框架結構了 那麼我們可以望文生意地就猜到tomcat的啟動 會先啟動父容器然後逐個啟動裡面的子容器 啟動每一個容器的時候 都會啟動安插在他身上的組件 當所有的組件啟動完畢 所有的容器啟動完畢的時候 tomcat本身也就啟動完畢了
順理成章地 我們同樣可以猜到 tomcat的啟動會分成兩大部分 第一步是裝配工作 第二步是啟動工作
裝配工作就是為父容器裝上子容器 為各個容器安插進組件的工作 這個地方我們會用到digester模式 至於digester模式什麼 有什麼用 怎麼工作的 請參考
啟動工作是在裝配工作之後 一旦裝配成功了 我們就只需要點燃最上面的一根導線 整個tomcat就會被激活起來 這就好比我們要開一輛已經裝配好了的汽車的時候一樣我們只要把鑰匙插進鑰匙孔一擰汽車的引擎就會發動起來空調就會開起來 安全裝置就會生效 如此一來汽車整個就發動起來了(這個過程確實和TOMCAT的啟動過程不謀而和 讓我們不得不懷疑 TOMCAT的設計者是在GE做JAVA開發的)
一些有意思的名稱
Catalina
Tomcat
Bootstrap
Engin
Host
Context
他們的意思很有意思
Catalina: 遠程轟炸機
Tomcat: 熊貓轟炸機 轟炸機的一種(這讓我想起了讓國人引以為豪的熊貓手機是不是英文可以叫做tomcat??? 又讓我想起了另一則廣告 波導手機中的戰斗機波音客機中的戰斗機 )
Bootstap: 引導
Engin: 發動機
Host: 主機領土
Context: 內容 目標 上下文
在許多許多年後 現代人類已經滅絕 後現代生物發現了這些單詞零落零落在一塊 一個自以為聰明的家伙把這些東西翻譯出來了
在地勤人員的引導(bootstrap)下 一架轟炸架(catalina)騰空躍起 遠看是熊貓轟炸機(tomcat) 近看還是熊貓轟炸機! 憑借著優秀的發動機技術(engin) 這架熊貓轟炸機飛臨了敵國的領土上空(host) 對准目標(context)投下了毀天滅地的核彈頭波~ 現代生物就這麼隔屁了~
綜上所述 這又不得不讓人聯想到GE是不是也參與了軍事設備的生產呢?
反對美帝國主義! 反對美霸權主義! 和平萬歲! 自由萬歲!
歷史就是那麼驚人的相似! tomcat的啟動就是從orgapachecatalinastartupBootstrap這個類悍然啟動的!
在Bootstrap裡做了兩件事
指定了種類型classloader:
commonLoader: common/classescommon/libcommon/endorsed
catalinaLoader: server/classesserver/libcommonLoader
sharedLoader shared/classesshared/libcommonLoader
引導Catalina的啟動
用Reflection技術調用orgapachecatalinastartupCatalina的process方法 並傳遞參數過去
Catalinajava
Catalina完成了幾個重要的任務
使用Digester技術裝配tomcat各個容器與組件
裝配工作的主要內容是安裝各個大件 比如server下有什麼樣的servcie Host會容納多少個context Context都會使用到哪些組件等等
同時呢 在裝配工作這一步 還完成了mbeans的配置工作 在這裡我簡單地但不十分精確地描述一下mbean是什麼干什麼用的
我們自己生成的對象 自己管理 天經地義! 但是如果我們創建了對象了 想讓別人來管 怎麼辦呢? 我想至少得告訴別人我們都有什麼 以及通過什麼方法可以找到 吧! JMX技術給我們提供了一種手段 JMX裡面主要有種東西Mbean agent connector
Mbean 用來映射我們的對象也許mbean就是我們創建的對象 也許不是 但有了它 就可以引用到我們的對象了
Agent: 通過它 就可以找到mbean了
Connector: 連接Agent的方式 可以是http的 也可以是rmi的還可以直接通過socket
發生在tomcat 裝配過程中的事情: GlobalResourcesLifecycleListener 類的初始化會被觸發
protected static Registry registry = MBeanUtilscreateRegistry(); 會運行
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28143.html