Apache Tomcat,一般稱爲Tomcat服務器,是一個開源的java servlet容器由Apache軟件基金會(ASF)開發。Tomcat實現了幾個java EE規範包括java servlet和JavaServer Pages(JSP),java EL和WebSocket,並提供了一個「純java」HTTP Web服務器環境中的java代碼能夠運行。html
總體架構
組件
如下說明以tomcat 8.0 版本爲前提java
Catalinaweb
Calalina是Tomcat的servlet容器。Calalina實現了Sun MyStand對Servlet和JavaServer頁面(JSP)的規範。在Tomcat中,領域元素表示分配給這些用戶的用戶名、密碼和角色(相似於UNIX組)的「數據庫」。領域的不一樣實現容許Calalina集成到已經建立和維護這樣的認證信息的環境中,而後使用servlet規範中描述的信息來實現容器管理的安全性。數據庫
Serverapache
Server:服務器的意思,表明整個tomcat服務器,一個tomcat只有一個Server;
Server是Tomcat最頂層的容器,表明着整個服務器,即一個Tomcat只有一個Server,Server中包含至少一個Service組件,用於提供具體服務。這個在配置文件中也獲得很好的體現(port=」8005」 shutdown=」SHUTDOWN」是在8005端口監聽到」SHUTDOWN」命令,服務器就會中止)。tomcat
service
Service:Server中的一個邏輯功能層, 一個Server能夠包含多個Service;安全
接收客戶端的請求,而後解析請求,完成相應的業務邏輯,而後把處理後的結果返回給客戶端,通常會提供兩個節本方法,一個start打開服務Socket鏈接,監聽服務端口,一個stop中止服務釋放網絡資源。服務器
Connector
稱做鏈接器,是Service的核心組件之一,一個Service能夠有多個Connector,主要是鏈接客戶端請求;
用於接受請求並將請求封裝成Request和Response,而後交給Container進行處理,Container處理完以後在交給Connector返回給客戶端。markdown
一個Connector會監聽一個獨立的端口來處理來自客戶端的請求。server.xml默認配置了兩個Connector:
,它監聽端口8080,這個端口值能夠修改,connectionTimeout定義了鏈接超時時間,單位是毫秒,redirectPort 定義了ssl的重定向接口,根據上述配置,Connector會將ssl請求轉發到8443端口。
, AJP表示Apache Jserv Protocol,它將處理Tomcat和Apache http服務器之間的交互,此鏈接器用於處理咱們將Tomcat和Apache http服務器結合使用的狀況,如在同一臺物理Server上部署一個Apache http服務器和多臺Tomcat服務器,經過Apache服務器來處理靜態資源以及負載均衡時,針對不一樣的Tomcat實例須要AJP監聽不一樣的端口。
Connector使用ProtocolHandler來處理請求的,不一樣的ProtocolHandler表明不一樣的鏈接類型,好比:Http11Protocol使用的是普通Socket來鏈接的(tomcat9已經刪除了這個類,再也不採用BIO的方式),Http11NioProtocol使用的是NioSocket來鏈接的。網絡
其中ProtocolHandler由包含了三個部件:Endpoint、Processor、Adapter。
1. Endpoint用來處理底層Socket的網絡鏈接,Processor用於將Endpoint接收到的Socket封裝成Request(這個Request和ServletRequest無關),Adapter充當適配器,用於將Request轉換爲ServletRequest交給Container進行具體的處理。
2. Endpoint因爲是處理底層的Socket網絡鏈接,所以Endpoint是用來實現TCP/IP協議的,而Processor用來實現HTTP協議的,Adapter將請求適配到Servlet容器進行具體的處理。
3. Endpoint的抽象實現AbstractEndpoint裏面定義的Acceptor和AsyncTimeout兩個內部類和一個Handler接口。Acceptor用於監聽請求,AsyncTimeout用於檢查異步Request的超時,Handler用於處理接收到的Socket,在內部調用Processor進行處理。
Container
Service的另外一個核心組件,按照層級有Engine,Host,Context,Wrapper四種,一個Service只有一個Engine,其主要做用是執行業務邏輯;
但若是將請求監聽和請求處理放在一塊兒,擴展性會變差,畢竟網絡協議不止HTTP一種,若是想適配多種網絡協議,請求處理又相同,這時就無能爲力了,tomcat的設計大師不會採起這種作法,而是將請求監聽和請求處理分開爲兩個模塊,分別是Connector和Container,Connector負責處理請求監聽,Container負責處理請求處理。
但顯然tomcat能夠有多個Connector,同時Container也能夠有多個。那這就存在一個問題,哪一個Connector對應哪一個Container,提供複雜的映射嗎?相信看過server.xml文件的人已經知道了tomcat是怎麼處理的了。
沒錯,Service就是這樣來的。在conf/server.xml文件中,能夠看到Service組件包含了Connector組件和Engine組件(前面有提過,Engine就是一種容器),即Service至關於Connector和Engine組件的包裝器,將一個或者多個Connector和一個Engine創建關聯關係。在默認的配置文件中,定義了一個叫Catalina 的服務,它將HTTP/1.1和AJP/1.3這兩個Connector與一個名爲Catalina 的Engine關聯起來。
一個Server能夠包含多個Service(它們相互獨立,只是公用一個JVM及類庫),一個Service負責維護多個Connector和一個Container。
Engine
一個Service中有多個Connector和一個Engine,Engine表示整個Servlet引擎,一個Engine下面能夠包含一個或者多個Host,即一個Tomcat實例能夠配置多個虛擬主機,默認的狀況下 conf/server.xml 配置文件中 定義了一個名爲Catalina的Engine。
Host
Host,表明一個站點,也能夠叫虛擬主機,一個Host能夠配置多個Context,在server.xml文件中的默認配置爲, 其中appBase=webapps, 也就是\webapps目錄,unpackingWARS=true 屬性指定在appBase指定的目錄中的war包都自動的解壓,autoDeploy=true 屬性指定對加入到appBase目錄的war包進行自動的部署。
一個Engine包含多個Host的設計,使得一個服務器實例能夠承擔多個域名的服務,是很靈活的設計。
Context
Context,表明一個應用程序,就是平常開發中的web程序,或者一個WEB-INF目錄以及下面的web.xml文件,換句話說每個運行的webapp最終都是以Context的形式存在,每一個Context都有一個根路徑和請求路徑;與Host的區別是Context表明一個應用,如,默認配置下webapps下的每一個目錄都是一個應用,其中ROOT目錄中存放主應用,其餘目錄存放別的子應用,而整個webapps是一個站點。
在Tomcat中一般採用以下方式建立一個Context:
1. 在\webapps 目錄中建立一個目錄dirname,此時將自動建立一個context,默認context的訪問url爲http://host:port/dirname,也能夠經過在ContextRoot\META-INF 中建立一個context.xml文件,其中包含以下內容來指定應用的訪問路徑:
2. 在server.xml文件中增長context 元素,以下:
這樣就能夠經過http://host:port/urlpath訪問上面配置的應用。
Wrapper
一個Context能夠包含多個Servlet處理不一樣請求,固然如今的SpringMVC,struts框架的出現致使程序中再也不是大量的Servlet,但其實本質是沒變的,都是由Servlet來處理或者看成入口。
在tomcat中Servlet被稱爲wrapper,其標準類圖以下:
那麼爲何要用Wrapper來表示Servlet?這和tomcat的處理機制有關,爲了更加靈活,便於擴展,tomcat是用管道(pipeline)和閥(valve)的形式來處理請求,因此將Servlet丟給Wrapper。這個後續再分析。
那麼如今tomcat就是這樣的:
Coyote
CyoOt是Tomcat的一個鏈接器組件,支持ajp、http1.一、spdy三種協議。
一、http
默認狀況下,HTTP鏈接器使用Tomcat進行安裝,並準備使用。該鏈接器具備最低的等待時間和最佳的總體性能。
對於集羣,必須安裝支持Web會話粘性的HTTP負載平衡器,以將流量引導到Tomcat服務器。Tomcat支持Adache HTTP Server 2 .x上的MODJOXER代理,並在默認狀況下包含在Apache HTTP服務器2.2中做爲負載均衡器。應該注意的是,HTTP代理的性能一般低於AJP的性能,因此AJP聚類一般是優選的。
二、ajp
當使用單個服務器時,在Tomcat實例前面使用 native webserver時的性能大部分時間都比具備默認HTTP鏈接器的獨立Tomcat更差,即便Web應用程序的很大一部分是由靜態文件構成的。若是出於任何緣由須要與本機WebServer集成,AJP鏈接器將提供比代理HTTP更快的性能。從Tomcat的角度來看,AJP聚類是最有效的。它在功能上等同於HTTP集羣。
此Tomcat版本支持的本機鏈接器爲:
JK 1.2 .x與任何支持的服務器
Apache HTTP Server 2 .x(默認狀況下包含在Apache HTTP服務器2.2中)的MODY代理,啓用了AJP
三、spdy
還有對SPDY協議的支持,儘管SPDY還不夠完善。
Jasper
Tomcat的JSP引擎。解析JSP文件編譯成java代碼的servlet(能夠處理卡特琳娜)。在運行時,Jasper檢測到對JSP文件的更改並從新編譯它們。
在版本5中,Tomcat使用JasPar 2,它是Sun MyStices的JSP 2規範的一個實現。從Jasper到Jasper2,增長了重要的特徵:
JSP標記庫池——JSP文件中的每一個標記標記由標記處理程序類處理。能夠在整個JSP servlet中聚集並重用標記處理程序類對象。
背景JSP編譯,編譯修改JSP java代碼,舊的版本仍然是可用的服務器的請求。舊JSP servlet一旦新的JSP servlet完成從新編譯就被刪除。
在包含頁面更改時從新編譯JSP——能夠在運行時插入頁面並將其包含到JSP中。JSP不只能夠用JSP文件更改從新編譯,並且還能夠包含頁面更改。
java編譯器JDT -Jasper2可使用Eclipse JDT(java開發工具)而不是螞蟻和java編譯器javac。
添加三個新的組分,釋放Tomcat 7:
Cluster
This component has been added to manage large applications. It is used for load balancing that can be achieved through many techniques. Clustering support currently requires the JDK version 1.5 or higher.
High availability
A high-availability feature has been added to facilitate the scheduling of system upgrades (e.g. new releases, change requests) without affecting the live environment. This is done by dispatching live traffic requests to a temporary server on a different port while the main server is upgraded on the main port. It is very useful in handling user requests on high-traffic web applications.[6]
Web application
It has also added user- as well as system-based web applications enhancement to add support for deployment across the variety of environments. It also tries to manage sessions as well as applications across the network.
Tomcat is building additional components. A number of additional components may be used with Apache Tomcat. These components may be built by users should they need them or they can be downloaded from one of the mirrors.[7]
啓動流程
tomcat的啓動流程很標準化,入口是BootStrap,統一按照生命週期管理接口Lifecycle的定義進行啓動。首先,調用init()方法逐級初始化,接着調用start()方法進行啓動,同時,每次調用伴隨着生命週期狀態變動事件的觸發。
每一級組件除完成自身的處理外,還有負責調用子組件的相關調用,組件和組件之間是鬆耦合的,能夠經過配置進行修改。
大體流程圖以下:
機制
生命週期
tomcat爲全部的組件都提供了生命週期管理,繼承LifecycleMBeanBase則跟tomcat中的生命週期機制有關。
參考資料
https://tomcat.apache.org/tomcat-8.5-doc/default-servlet.html