Tomcat 处理 HTTP 请求源码分析(上)【转】
原文地址:https://www.infoq.cn/article/zh-tomcat-http-request-1
很多開(kāi)源應(yīng)用服務(wù)器都是集成 tomcat 作為 web container 的,而且對(duì)于 tomcat 的 servlet container 這部分代碼很少改動(dòng)。這樣,這些應(yīng)用服務(wù)器的性能基本上就取決于 Tomcat 處理 HTTP 請(qǐng)求的 connector 模塊的性能。本文首先從應(yīng)用層次分析了 tomcat 所有的 connector 種類及用法,接著從架構(gòu)上分析了 connector 模塊在整個(gè) tomcat 中所處的位置,最后對(duì) connector 做了詳細(xì)的源代碼分析。并且我們以 Http11NioProtocol 為例詳細(xì)說(shuō)明了 tomcat 是如何通過(guò)實(shí)現(xiàn) ProtocolHandler 接口而構(gòu)建 connector 的。
通過(guò)本文的學(xué)習(xí),應(yīng)該可以輕松做到將 tomcat 做為 web container 集成到第三方系統(tǒng),并且自定義任何你想要的高性能的 HTTP 連接器。
1 Connector 介紹
1.1 Connector 的種類
Tomcat 源碼中與 connector 相關(guān)的類位于 org.apache.coyote 包中,Connector 分為以下幾類:
- Http Connector, 基于 HTTP 協(xié)議,負(fù)責(zé)建立 HTTP 連接。它又分為 BIO Http Connector 與 NIO Http Connector 兩種,后者提供非阻塞 IO 與長(zhǎng)連接 Comet 支持。
- AJP Connector, 基于 AJP 協(xié)議,AJP 是專門設(shè)計(jì)用來(lái)為 tomcat 與 http 服務(wù)器之間通信專門定制的協(xié)議,能提供較高的通信速度和效率。如與 Apache 服務(wù)器集成時(shí),采用這個(gè)協(xié)議。
- APR HTTP Connector, 用 C 實(shí)現(xiàn),通過(guò) JNI 調(diào)用的。主要提升對(duì)靜態(tài)資源(如 HTML、圖片、CSS、JS 等)的訪問(wèn)性能。現(xiàn)在這個(gè)庫(kù)已獨(dú)立出來(lái)可用在任何項(xiàng)目中。Tomcat 在配置 APR 之后性能非常強(qiáng)勁。
1.2 Connector 的配置
對(duì) Connector 的配置位于 conf/server.xml 文件中。
1.2.1 BIO HTTP/1.1 Connector 配置
一個(gè)典型的配置如下:
<Connector port=”8080” protocol=”HTTP/1.1” maxThreads=”150” connectionTimeout=”20000” redirectPort=”8443”其它一些重要屬性如下:
- acceptCount : 接受連接 request 的最大連接數(shù)目,默認(rèn)值是 10
- address : 綁定 IP 地址,如果不綁定,默認(rèn)將綁定任何 IP 地址
- allowTrace : 如果是 true, 將允許 TRACE HTTP 方法
- compressibleMimeTypes : 各個(gè) mimeType, 以逗號(hào)分隔,如 text/html,text/xml
- compression : 如果帶寬有限的話,可以用 GZIP 壓縮
- connectionTimeout : 超時(shí)時(shí)間,默認(rèn)為 60000ms (60s)
- maxKeepAliveRequest : 默認(rèn)值是 100
- maxThreads : 處理請(qǐng)求的 Connector 的線程數(shù)目,默認(rèn)值為 200
如果是 SSL 配置,如下:
<Connector port="8181" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol = "TLS" address="0.0.0.0" keystoreFile="E:/java/jonas-full-5.1.0-RC3/conf/keystore.jks" keystorePass="changeit" />其中,keystoreFile 為證書位置,keystorePass 為證書密碼
1.2.2 NIO HTTP/1.1 Connector 配置
<Connector port=”8080” protocol=”org.apache.coyote.http11.Http11NioProtocol” maxThreads=”150” connectionTimeout=”20000” redirectPort=”8443”1.2.3 Native APR Connector 配置
tcnative-1.dll 與 openssl.exe,將其放在 %tomcat%\bin 目錄下。
下載地址是:http://tomcat.heanet.ie/native/1.1.10/binaries/win32/
maxThreads=”150” connectionTimeout=”20000” redirectPort=”8443”
2 Connector 在 Tomcat 中所處的位置
2.1 Tomcat 架構(gòu)
圖 2-1 Tomcat 架構(gòu)
- Server(服務(wù)器) 是 Tomcat 構(gòu)成的頂級(jí)構(gòu)成元素,所有一切均包含在 Server 中,Server 的實(shí)現(xiàn)類 StandardServer 可以包含一個(gè)到多個(gè) Services;
- 次頂級(jí)元素 Service 的實(shí)現(xiàn)類為 StandardService 調(diào)用了容器 (Container) 接口,其實(shí)是調(diào)用了 Servlet Engine(引擎),而且 StandardService 類中也指明了該 Service 歸屬的 Server;
- 接下來(lái)次級(jí)的構(gòu)成元素就是容器 (Container),主機(jī) (Host)、上下文 (Context) 和引擎 (Engine) 均繼承自 Container 接口,所以它們都是容器。但是,它們是有父子關(guān)系的,在主機(jī) (Host)、上下文 (Context) 和引擎 (Engine) 這三類容器中,引擎是頂級(jí)容器,直接包含是主機(jī)容器,而主機(jī)容器又包含上下文容器,所以引擎、主機(jī)和上下文從大小上來(lái)說(shuō)又構(gòu)成父子關(guān)系,雖然它們都繼承自 Container 接口。
- 連接器 (Connector) 將 Service 和 Container 連接起來(lái),首先它需要注冊(cè)到一個(gè) Service,它的作用就是把來(lái)自客戶端的請(qǐng)求轉(zhuǎn)發(fā)到 Container(容器),這就是它為什么稱作連接器的原因。
故我們從功能的角度將 Tomcat 源代碼分成 5 個(gè)子模塊,它們分別是:
2.2 Tomcat 運(yùn)行流程
圖 2-2 tomcat 運(yùn)行流程
假設(shè)來(lái)自客戶的請(qǐng)求為:http://localhost:8080/test/index.jsp
3 Connector 源碼分析
3.1 Tomcat 的啟動(dòng)分析與集成設(shè)想
我們知道,啟動(dòng) tomcat 有兩種方式:
- 雙擊 bin/startup.bat
- 運(yùn)行 bin/catalina.bat run
它們對(duì)應(yīng)于 Bootstrap 與 Catalina 兩個(gè)類,我們現(xiàn)在只關(guān)心 Catalina 這個(gè)類,這個(gè)類使用 Apache Digester 解析 conf/server.xml 文件生成 tomcat 組件,然后再調(diào)用 Embedded 類的 start 方法啟動(dòng) tomcat。
所以,集成 Tomcat 的方式就有以下兩種了:
- 沿用 tomcat 自身的 server.xml
- 自己定義一個(gè) xml 格式來(lái)配置 tocmat 的各參數(shù),自己再寫解析這段 xml,然后使用 tomcat 提供的 API 根據(jù)這些 xml 來(lái)生成 Tomcat 組件,最后調(diào)用 Embedded 類的 start 方法啟動(dòng) tomcat
個(gè)人覺(jué)得第一種方式要優(yōu)越,給開(kāi)發(fā)者比較好的用戶體驗(yàn),如果使用這種,直接模仿 Catalina 類的方法即可實(shí)現(xiàn)集成。
目前,JOnAS 就使用了這種集成方式,JBoss、GlassFish 使用的第二種自定義 XML 的方式。
3.2 Connector 類圖與順序圖
圖 3-1 Connector 相關(guān)類圖
圖 3-2 Connector 工作流程順序圖
從上面二圖中我們可以得到如下信息:
圖 3-3 自定義 connector 時(shí)需實(shí)現(xiàn)的 ProtocolHandler 接口
Tomcat 以 HTTP(包括 BIO 與 NIO)、AJP、APR、內(nèi)存四種協(xié)議實(shí)現(xiàn)了該接口(它們分別是:AjpAprProtocol、AjpProtocol、Http11AprProtocol、Http11NioProtocol、Http11Protocal、JkCoyoteHandler、MemoryProtocolHandler),要使用哪種 Connector 就在 conf/server.xml 中配置,在 Connector 的構(gòu)造函數(shù)中會(huì)通過(guò)反射實(shí)例化所配置的實(shí)現(xiàn)類:
<Connector port="8181" protocol="org.apache.coyote.http11.Http11AprProtocol " />3.3 Connector 的工作流程
下面我們以 Http11AprProtocol 為例說(shuō)明 Connector 的工作流程。
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/11249466.html
總結(jié)
以上是生活随笔為你收集整理的Tomcat 处理 HTTP 请求源码分析(上)【转】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 手写一个迷你版的 Tomcat 喵【转】
- 下一篇: Tomcat 处理 HTTP 请求源码分