Tomcat請(qǐng)求處理在源碼中的輪轉(zhuǎn)解析
Tomcat基礎(chǔ)架構(gòu)
Tomcat作為Java開(kāi)發(fā)者接觸過(guò)最重要的web容器,在啟動(dòng)和處理請(qǐng)求過(guò)程中做了海量的事情,初級(jí)開(kāi)發(fā)者很少關(guān)心,使用SpringMvc之類(lèi)上層框架一帶而過(guò),然而這些部分是Java和網(wǎng)絡(luò)集大成之作,筆者要帶著大家走一遍一次請(qǐng)求,加深tomcat的認(rèn)知。最好先調(diào)試好Tomcat源碼
BootStrap和Catalina
BootStrap
BootStrap就是Tomcat的main函數(shù)所在位置,在使用過(guò)程中執(zhí)行腳本catlina.sh或者bat文件即可執(zhí)行java命令并調(diào)用BootStrap的main函數(shù)實(shí)現(xiàn)tomcat的啟動(dòng)
public static void main(String args[]) {
if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.init();
} catch (Throwable t) {
handleThrowable(t);
t.printStackTrace();
return;
}
daemon = bootstrap;
} else {
// When running as a service the call to stop will be on a new
// thread so make sure the correct class loader is used to
// prevent a range of class not found exceptions.
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
}
......
}Catalina
BootStrap是服務(wù)器的入口, 會(huì)通過(guò)start、stop、stopServer、stopServer等反射調(diào)用Catalina的對(duì)應(yīng)方法
public void stopServer() throws Exception {
Method method =
catalinaDaemon.getClass().getMethod("stopServer", (Class []) null);
method.invoke(catalinaDaemon, (Object []) null);
}Tomcat的核心配置文件server.xml
先來(lái)看一下tomcat的容器結(jié)構(gòu)

tomcat容器有多層,Server、service、Engine、Host、Context等,圖中有省略
比如一個(gè)名稱(chēng)為mytomcat的web項(xiàng)目,對(duì)應(yīng)到Container部分,Context名稱(chēng)就是mytomcat
再看一下Tomcat的配置文件server.xml
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener SSLEngine="on"
className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource auth="Container" description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase"
pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector URIEncoding="UTF-8" connectionTimeout="20000"
port="80" protocol="HTTP/1.1" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine defaultHost="localhost" name="Catalina">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
</Realm>
<Host appBase="webapps" autoDeploy="true" name="localhost"
unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log."
suffix=".txt" />
</Host>
</Engine>
</Service>在啟動(dòng)tomcat的時(shí)候,catalina的load方法,會(huì)讀取server.xml文件的內(nèi)容,通過(guò)Digester組件把server.xml解析成Server對(duì)象,并且把Server變成Catalina的成員變量。
我們看一下catalina的load方法中digester.parse()方法執(zhí)行后的容器代碼結(jié)構(gòu)

這樣的話,Tomcat的容器的層級(jí)結(jié)構(gòu)就建立起來(lái)了。
網(wǎng)絡(luò)處理部分
Connector
tomcat可以處理多種協(xié)議,統(tǒng)一使用Connector組件來(lái)實(shí)現(xiàn),在tomcat中一個(gè)Service可以對(duì)應(yīng)多個(gè)Connector

ProtocolHandler
connector中有個(gè)很重要的成員變量protocolHandler, 用來(lái)實(shí)現(xiàn)多種協(xié)議的解析,

比如http協(xié)議。基于tcp做集群的AJP協(xié)議
Endpoint
AbstractEndpoint是Tcp的處理入口,并且持有Executor;Connector的executor和ProtocolHandler的線程池都是使用這個(gè)executor
當(dāng)有網(wǎng)絡(luò)任務(wù)到來(lái)的時(shí)候,tomcat會(huì)使用這個(gè)線程池來(lái)處理socket事件

Acceptor 和 Poller
Acceptor是封裝新連接的任務(wù),Endpoint使用單獨(dú)的線程維護(hù) Poller 是java NIO中Selector的封裝,當(dāng)新連接到來(lái)時(shí)喚醒Acceptor線程注冊(cè)pollerEvent事件來(lái)監(jiān)聽(tīng)連接

Poller的實(shí)現(xiàn)是java的Selector

以上就是Tomcat請(qǐng)求處理在源碼中的輪轉(zhuǎn)解析的詳細(xì)內(nèi)容,更多關(guān)于Tomcat請(qǐng)求處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
ngin配置301重定向設(shè)置方法和nginx子目錄301重定向
這篇文章主要介紹了ngin配置301重定向設(shè)置方法和nginx子目錄301重定向,需要的朋友可以參考下2014-04-04
nginx+apache+mysql+php+memcached+squid搭建集群web環(huán)境
當(dāng)前,LAMP開(kāi)發(fā)模式是WEB開(kāi)發(fā)的首選,如何搭建一個(gè)高效、可靠、穩(wěn)定的WEB服務(wù)器一直是個(gè)熱門(mén)主題,本文就是這個(gè)主題的一次嘗試。2011-03-03
NGINX報(bào)錯(cuò)413 Request Entity Too Large的問(wèn)題解決
Nginx 413錯(cuò)誤表示請(qǐng)求實(shí)體太大,本文主要介紹了NGINX報(bào)錯(cuò)413 Request Entity Too Large的問(wèn)題解決,具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-08
nginx禁止某個(gè)IP訪問(wèn)站點(diǎn)的設(shè)置方法
近期發(fā)現(xiàn)博客遭到某些人的惡意灌水,頻繁地利用發(fā)帖機(jī)器人發(fā)表評(píng)論,給博客的管理帶來(lái)諸多不便,搜索了一下資料,可以利用nginx的ngx_http_access_module 模塊設(shè)置允許/禁止哪些ip或ip段訪問(wèn)站點(diǎn)。2010-12-12
nginx http響應(yīng)限速的具體實(shí)現(xiàn)
本文主要介紹了nginx http響應(yīng)限速的具體實(shí)現(xiàn),可以使用limite_rate和limit_rate_after來(lái)限制HTTP響應(yīng)的速度,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05
Nginx反向代理后端接口解決跨域沖突、預(yù)檢報(bào)錯(cuò)問(wèn)題全流程
本文詳細(xì)記錄了作者如何通過(guò)Nginx配置優(yōu)化,解決多域名訪問(wèn)后端接口、Nginx反向代理及后端自帶跨域配置導(dǎo)致的跨域問(wèn)題,主要內(nèi)容包括分析問(wèn)題根源、屏蔽后端跨域頭、配置多域名白名單、攔截OPTIONS預(yù)檢請(qǐng)求、常規(guī)接口統(tǒng)一附加跨域頭,并提供了完整的Nginx配置示例2026-04-04
Nginx?Rewrite及Location的使用與區(qū)別
rewrite和location的功能有點(diǎn)相像,都能實(shí)現(xiàn)跳轉(zhuǎn),本文主要介紹了Nginx?Rewrite及Location的使用與區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08

