Tomcat connector 实现原理
Bootstrap.main()->Bootstrap.init()
bootstrap.init() 方法中設(shè)置catalinaDaemon
創(chuàng)建 Connector 對(duì)象
Bootstrap.main()->Bootstrap.start()->Catalina.start()->Catalina.load()->Catalina.createStartDigester()
createStartDigester() 方法
1. 創(chuàng)建connector對(duì)象,并判斷server.xml 中是否配置線程池,如果配置線程池則創(chuàng)建線程池
Connector
構(gòu)造
通過(guò)protocol協(xié)議來(lái)判斷使用那個(gè)protocolHandler。
setProtocol 方法
tomcat 默認(rèn)配置 是以BIO的模式啟動(dòng)的,默認(rèn)會(huì)調(diào)用org.apache.coyote.http11.Http11Protocol。
下面我們以Http11Protocol來(lái)分析Connector。
startInternal() 方法
1. 設(shè)置tomcat狀態(tài)為,正在啟動(dòng)
2. 啟動(dòng) connector。
Http11Protocol
AbstractEndpoint.start() 方法
public class JIoEndpoint extends AbstractEndpointJIoEndpoint 繼承 AbstractEndpoint
JIoEndpoint .bind() 方法
在這創(chuàng)建connector的socket服務(wù),使用serverSocket監(jiān)聽(tīng)入站連接。
JIoEndpoint.startInternal() 方法
1. 判斷線程池是否為空,如果為空則創(chuàng)建默認(rèn)的線程池。(server.xml的connector中配置的線程池)
2. 根據(jù)server.xml中的connector中的acceptorThreadCount屬性來(lái)確定創(chuàng)建幾個(gè)接受請(qǐng)求處理的線程。
Acceptor類,負(fù)責(zé)處理接受客戶端請(qǐng)求的處理。
server.xml 中配置如下:
acceptorThreadCount 個(gè)數(shù)建議和CPU的個(gè)數(shù)一致。
createExecutor() 方法
默認(rèn)創(chuàng)建的線程池,最小線程數(shù)為10,最大線程數(shù)為200,空閑時(shí)間為60秒,隊(duì)列為L(zhǎng)inkedBlockingQueue,隊(duì)列大小默認(rèn)為Ineteger.MAX_VALUE。
這里需要注意的是,如果隊(duì)列中的元素沒(méi)有存滿,那么線程的數(shù)量一直會(huì)是10,而不會(huì)自動(dòng)擴(kuò)大到200。所以建議大家自己設(shè)置一個(gè)線程池,而不要用默認(rèn)的
Acceptor 類
Acceptor.run() 方法
2.設(shè)置socket的參數(shù)
processSocket() 方法
把socket封裝成SocketWrapper對(duì)象 傳給SocketProcessor對(duì)象,并提交給線程池處理。
SocketProcessor
負(fù)責(zé)解析http協(xié)議信息。
SOcketProcessor重要屬性
inputBuffer:包裝socket的inputStream,并解析http協(xié)議信息。
outputBuffer:包裝socket的outputStream,負(fù)責(zé)響應(yīng)用戶的數(shù)據(jù)。
run() 方法
在process方法中處理解析http協(xié)議信息。
Http11Processor.process() 方法
Http11Protocol.process()->Http11Processor.process() 代碼如下:
獲取socket的輸入流和輸出流
Http11Processor構(gòu)造方法
在這里,構(gòu)造Request和Response對(duì)象。
解析http協(xié)議
解析完后的數(shù)據(jù)存儲(chǔ)到 AbstractInputBuffer的下面兩個(gè)屬性中
protected Request request;protected MimeHeaders headers;request對(duì)象就是 HttpServletRequest 對(duì)象的原型。
解析完之后,調(diào)用下面的service方法。
這里的service方法會(huì)調(diào)用servlet中的service方法并傳入request和response對(duì)象,然后根據(jù)請(qǐng)求的方法來(lái)決定調(diào)用的是servlet的doGet方法還是doPost或其它的方法。
到此 Connector的整理流程就結(jié)束了。
簡(jiǎn)單梳理下
1. Connector
根據(jù)協(xié)議來(lái)選擇協(xié)議的處理類,tomcat默認(rèn)的處理類是Http11Protocol。
2. JIoEndpoint
3. Http11Processor
主要負(fù)責(zé)解析http協(xié)議的
1. 解析請(qǐng)求行 (來(lái)確定http協(xié)議、請(qǐng)求的url、請(qǐng)求的method)
2. 解析請(qǐng)求頭 headers
3.并把解析后的結(jié)果交給 Container 處理
connector 可配置的部分參數(shù)
參數(shù)值根據(jù)自己項(xiàng)目做響應(yīng)修改。下面的只是個(gè)例子
<Connector port="8080" protocol="HTTP/1.1"acceptCount="1000"disableUploadTimeout="true"enableLookups="false"keepAliveTimeout="20"maxThreads="500" minThreads="500"maxProcessor="500"minSpareThreads="20"maxKeepAliveRequests="1"connectionTimeout="20" redirectPort="8443"allowTrace="false"acceptorThreadCount="2"acceptorThreadPriority="7"socket.tcpNoDelay="true"threadPriority="8"tcpNoDelay="true"compression="on"emptySessionPath="true" />本人簡(jiǎn)書(shū)blog地址:http://www.jianshu.com/u/1f0067e24ff8????
點(diǎn)擊這里快速進(jìn)入簡(jiǎn)書(shū)
GIT地址:http://git.oschina.net/brucekankan/
點(diǎn)擊這里快速進(jìn)入GIT
總結(jié)
以上是生活随笔為你收集整理的Tomcat connector 实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java.util.Random 实现原
- 下一篇: Tomcat Filter 源码分析