? ? 作為一枚java程序員遇伞,tomcat絕對是常接觸的web服務器辙喂,本人對tomcat源碼也垂涎已久。近日,終于在工作之余有了些許閑暇時間加派,學習之叫确,我試圖記錄學習的過程及結果,一來加深自己的學習印象芍锦,二來也分享我的學習過程竹勉,或許可以幫助一些同志們少走彎路。廢話到此結束娄琉,開始正題次乓。
? ? 1、源碼工程搭建
????源碼準備準備學習tomncat源碼第一步當然是下載tomcat源碼孽水,我下載的是最新的tomcat9的源碼(附上下載鏈接http://mirrors.shu.edu.cn/apache/tomcat/tomcat-9/v9.0.6/src/apache-tomcat-9.0.6-src.zip)下載完成后票腰,把源碼解壓出來。然后在工程目錄下創(chuàng)建一個pom.xml文件把它改成maven工程女气。pom里面內容如下:
4.0.0org.apache.tomcatTomcat9.0Tomcat9.09.0 Tomcat9.0 java test java test org.apache.maven.plugins maven-compiler-plugin 2.3 UTF-8 1.8 1.8 junit junit 4.12 test org.easymock easymock 3.4 ant ant 1.7.0 wsdl4j wsdl4j 1.6.2 javax.xml jaxrpc 1.1 org.eclipse.jdt.core.compiler ecj 4.5.1"
然后在項目根目錄下創(chuàng)建lib文件夾并把從網上下載編譯好的tomcat項目lib下jar包復制到該源碼lib文件夾下杏慰。然后打開idea 導入該tocmat maven項目。導入后項目目錄如圖:
然后配置啟動類如圖
配置完成后就可啟動tomcat項目炼鞠。啟動完成后在瀏覽器輸入http://localhost:8080/驗證下tomcat是否成功啟動成功缘滥。
2、tomcat9整體系統(tǒng)架構
tomcat源碼工程構建成功谒主,原本我以為可以愉快地debug學習了朝扼,但是理想是豐滿的,現(xiàn)實是骨感的霎肯。tomcat由于發(fā)展了很多年擎颖,現(xiàn)在整個源碼工程已經十分龐大,若對tomcat的整體架構沒有了解观游,單單靠著一步一步debug將是十分困難的搂捧。若想通過對源碼的學習來反推出它的系統(tǒng)架構或設計思想更是難上加難,終于經過我一夜的debug還是對tomcat設計思想和整體架構云里霧里后备典,我放棄了异旧,開始從網上尋找tomcat整體的設計思想和系統(tǒng)架構,先對tomcat整體有宏觀的理解提佣,然后分清主次吮蛹,不去太多的關注細節(jié),這樣才對tomcat源碼有了粗淺的認識拌屏。一下是我根據(jù)網上各位大神和自己對源碼的閱讀整理的tomcat整體架構的整理潮针。
先來一張有名的tomcat架構圖
我們來看看tomcat每個組件的作用是什么
2.1、Server
Server代表整個catalina servlet容器倚喂。它的特性代表servlet容器的整體特性每篷。Server可以包含一個或多個service瓣戚,以及頂級的命名資源集。通常焦读,此接口的實現(xiàn)子库,還將實現(xiàn)生命周期接口,這樣當start()和stop()方法被調用矗晃,所有它包含的service也開始或停止仑嗅。在兩者之間,實現(xiàn)必須在端口屬性指定的端口號上打開服務器套接字张症。當連接被接受時仓技,讀取第一行,并與指定的關閉命令進行比較俗他。如果命令匹配脖捻,則啟動服務器關機。注意兆衅,按圖上各個容器或組件的關系此接口的正確實現(xiàn)應該是一個單例的地沮。
2.2、service
service連接一組或多個Connector和一個Container涯保,他們一起來處理傳入的請求诉濒。也就是一個service把多個Connector和一個Container組裝起來才能對外提供服務周伦,二而service也需要生存的土壤這個土壤就是Server夕春。service的標準實現(xiàn)是StandardService它不僅實現(xiàn)了Service接口還實現(xiàn)了Lifycycle接口說明他的上級容器可以控制它的生命周期。
2.3专挪、Connector
Connector負責把接收到的請求解析出來然后封裝成request和response對象然后交給Container處理及志。目前Connector支持http和ajp協(xié)議。
2.4寨腔、Container
Container字面是容器的意思速侈。既然是容器里面肯定裝有東西,那么它裝的是什么呢迫卢?它裝著Engine倚搬、Host、Context和Wrapper這幾個容器乾蛤。他們是Container子類型每界。Engine(引擎)包含Host和Context,接到請求后仍給相應的Host在相應的Context里處理家卖。Host:就是我們所理解的虛擬主機眨层。Context:就是我們所部屬的具體Web應用的上下文,每個請求都在是相應的上下文里處理的上荡。Wrapper:Wrapper是針對每個Servlet的Container趴樱,每個Servlet都有相應的Wrapper來管理。
2.5、Component 組件:
需求被傳遞到了容器里面叁征, 在合適的時候纳账, 會傳遞給下一個容器處理。而容器里面又盛裝著各種各樣的組件捺疼, 我們可以理解為提供各種各樣的增值服務塞祈。比如:
manager: 當一個容器里面裝了manager組件后,這個容器就支持session管理了帅涂, 事實上在tomcat里面的session管理, 就是靠的在context里面裝的manager component.
logger: 當一個容器里面裝了logger組件后议薪, 這個容器里所發(fā)生的事情, 就被該組件記錄下來, 我們通常會在logs/ 這個目錄下看見catalina_log.time.txt 以及l(fā)ocalhost.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凸主, 把需求傳遞給當前容器的子容器橘券。 就是通過這種方式, 需求就在各個容器里面?zhèn)鬟f卿吐,流動旁舰, 最后抵達目的地的了。
valve: 就是上面所說的閥門但两。
Tomcat里面大概就是這么些東西鬓梅, 我們可以簡單地這么理解tomcat的框架横堡,它是一種自上而下祠墅, 容器里又包含子容器的這樣一種結構滨溉。
好了理解了整體架構我們后面來看看tomcat的更深層的技術。绳匀。椿胯。娩脾。