前言
最近想分析一下網絡請求的一些東東,okhttp大概核心部分的那個連接池看着實在讓人肝顫。就想着讀一個網絡後臺的程序,本來準備讀nginx。主要網絡請求部分基本分析清楚,但是http的URL處理以及解析讀着就比較蛋疼了,特別是爲了一些長的URL和body等等,包括socket數據的拼接等。讀着那c語言,最終還是放棄了。所以就轉頭讀一讀tomcat,畢竟tomcat不那麼在意性能嘛!大概看了下,設計確實吊炸天。
正文
關於如何ide調試,這裏可以自行百度,比較簡單。
首先最基本的套路,一個BootStrap,這裏不再詳細介紹,主要是一些自定義類加載器,暫時猜測主要是爲了安全性而出現的。根本目的是用來加載一個叫做Catalina的東東(叫什麼覺得都不適合,他就類似於操作系統的硬件,都沒什麼意義,又比較多的hardcode,用來加載優雅的tomcat的組件)。
不過我們還是需要了解一下catalina的主要流程。
Catalina主要是控制生命週期主要是用load
,加載一個Digester
來解析server.xml
(其他是用來初始化一些目錄啥的,懶得關注),來初始化整個tomcat。隨後調用start
來開啓整個tamcat。
這個Digester
,是個很奇葩的設計。他是解析xml文件的,解析文件是編程界的最大的痛,沒什麼人知道該如何優雅的解析,目前我瞭解的三種方法。
- hardcode,看到什麼就解析成成什麼
- 通過反射。
- 通過DSL類語言,把配置文件作爲方法調用(類似gradle)
目前毫無懷疑第三種最優雅,第二種其實類似於第一種,都需要大量的hardcode的編碼,不過第三種性能比較低,並且需要編程語言的支持。java目前不支持這種特性。
第二種在tomcat開發的時候,java還不存在反射,所以我們tomcat只能用第一種方案。不過爲了在非常不優雅的代碼中相對優雅的工作,我們搞出了一個職責鏈的解析初始化Tomcat的方法,每個標籤,搞一個rules,用來做出一系列先關操作,比如
digester.addObjectCreate("Server",
"org.apache.catalina.core.StandardServer",
"className");
digester.addSetProperties("Server");
digester.addSetNext("Server",
"setServer",
"org.apache.catalina.Server");
我們遇到Server標籤,就會出現這三個rule,然後分別在start和end做出相關動作,根據名字,因爲職責鏈分先後,第一個新建,第二個配置,第三個像父標籤配置先關參數。
我們只用配置四個東東,就可以啓動一個基本的tomcat具體如下
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"/>
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
</Host>
</Engine>
</Service>
</Server>
很清楚的看到這裏只有一個server,一個service,這倆都是只能有一個,這些都是概念性的東西,用於清晰代碼的邏輯。
下面東西就是真的也許邏輯了,
Connector(連接器) 主要是用來監聽特定端口生成request然後交給Adapter來處理
Engine ()主要裏面有個pipline,用來執行剛纔生產的request(代碼沒讀)
Host()也是處理request,但是各自職責不同,(代碼還沒讀)
emmm忽然就發覺事情搞定了,不過以後會把這三個在一一分析一下。
後記
我們貌似忽略了真正的解析jar包的部分,不過我們暫時主要盯着請求,以後有空再分析吧。