什麼是tomcat?tomcat是幹什麼用的?

一、什麼是Tomcat

Tomcat 是由 Apache 軟體基金會下屬的 Jakarta 專案開發的一個 Servlet 容器。是開源的輕量級Web應用伺服器。

二、tomcat結構目錄

①bin:啟動和關閉tomcat的bat檔案。

startup.bat , shutdown.bat    用於在windows下啟動和停止指令碼; startup.sh, shutdown.sh   用於在linux下啟動和停止指令碼;

②conf:配置檔案。

Catalina  用於儲存針對每個虛擬機器的Context配置 context.xml   用於定義所有web應用均需載入的Context配置,如果web應用指定了自己的context.xml ,該檔案將被覆蓋 catalina.properties   Tomcat 的環境變數配置 catalina.policy   Tomcat 執行的安全策略配置 logging.properties    Tomcat 的日誌配置檔案, 可以透過該檔案修改Tomcat 的日誌級別及日誌路徑等server.xml該檔案用於配置server相關的資訊,比如tomcat啟動的埠號,配置主機(Host)。 web.xml檔案配置與web應用(web應用相當於一個web站點) tomcat-user.xml配置使用者名稱密碼和相關許可權。

③lib:該目錄放置執行tomcat執行需要的jar包。

④logs:存放日誌,當我們需要檢視日誌的時候,可以查詢資訊。

⑤webapps:放置我們的web應用。

⑥work工作目錄:該目錄用於存放jsp被訪問後生成對應的server檔案和.class檔案。

啟動:雙擊 bin/startup.bat 檔案 ; 停止:雙擊 bin/shutdown.bat 檔案 ; 訪問:http://localhost:8080

三、Tomcat整體架構

1、Tomcat核心功能

我們已經瞭解了Tomcat要實現兩個核心功能

1) 處理Socket連線,負責網路位元組流與Request和Response物件的轉化。 2) 載入和管理Servlet,以及具體處理Request請求。

因此Tomcat設計了兩個核心元件聯結器(Connector)容器(Container)來分別做這兩件事情。聯結器負責對外交流,容器負責內部處理。

2、聯結器

聯結器中的各個元件的作用如下:1)EndPoint

EndPoint : Coyote 通訊端點,即通訊監聽的介面,是具體Socket接收和傳送處理器,是對傳輸層的抽象,因此EndPoint用來實現TCP/IP協議的。 Tomcat 並沒有EndPoint 介面,而是提供了一個抽象類AbstractEndpoint , 裡面定義了兩個內部類:Acceptor和SocketProcessor。Acceptor用於監聽Socket連線請求。SocketProcessor用於處理接收到的Socket請求,它實現Runnable介面,在Run方法裡呼叫協議處理元件Processor進行處理。為了提高處理能力,SocketProcessor被提交到執行緒池來執行。而這個執行緒池叫作執行器(Executor),我在後面的專欄會詳細介紹Tomcat如何擴充套件原生的Java執行緒池。

2) Processor Processor : Coyote 協議處理介面 ,如果說EndPoint是用來實現TCP/IP協議的,那麼Processor用來實現HTTP協議,Processor接收來自EndPoint的Socket,讀取位元組流解析成Tomcat Request和Response物件,並透過Adapter將其提交到容器處理,Processor是對應用層協議的抽象。

3)ProtocolHandler ProtocolHandler: Coyote 協議介面, 透過Endpoint 和 Processor , 實現針對具體協議的處理能力。Tomcat 按照協議和I/O 提供了6個實現類 : AjpNioProtocol , AjpAprProtocol, AjpNio2Protocol , Http11NioProtocol ,Http11Nio2Protocol ,Http11AprProtocol。我們在配置tomcat/conf/server.xml 時 , 至少要指定具體的ProtocolHandler , 當然也可以指定協議名稱 , 如 : HTTP/1.1 ,如果安裝了APR,那麼將使用Http11AprProtocol , 否則使用 Http11NioProtocol 。

4)Adapter 由於協議不同,客戶端發過來的請求資訊也不盡相同,Tomcat定義了自己的Request類來“存放”這些請求資訊。ProtocolHandler介面負責解析請求並生成Tomcat Request類。但是這個Request物件不是標準的ServletRequest,也就意味著,不能用Tomcat Request作為引數來呼叫容器。Tomcat設計者的解決方案是引入CoyoteAdapter,這是介面卡模式的經典運用,聯結器呼叫CoyoteAdapter的Sevice方法,傳入的是Tomcat Request物件,CoyoteAdapter負責將Tomcat Request轉成ServletRequest,再呼叫容器的Service方法。

3、容器

Tomcat設計了4種容器,分別是Engine、Host、Context和Wrapper。容器的功能是處理Connector接收進來的請求,併產生相應的響應,這4種容器不是平行關係,而是父子關係, Tomcat透過一種分層的架構,使得Servlet容器具有很好的靈活性。

1) Engine   表示整個Catalina的Servlet引擎,用來管理多個虛擬站點,一個Service最多隻能有一個Engine,但是一個引擎可包含多個Host 2)Host  代表一個虛擬主機,或者說一個站點,可以給Tomcat配置多個虛擬主機地址,而一個虛擬主機下可包含多個Context 3)Context   表示一個Web應用程式, 一個Web應用可包含多個Wrapper 4)Wrapper   表示一個Servlet,Wrapper 作為容器中的最底層,不能包含子容器

四、server.xml

server.xml是Tomcat中最重要的配置檔案,server.xml位於$TOMCAT_HOME/conf目錄下;server.xml的每一個元素都對應了Tomcat中的一個元件;透過對xml檔案中元素的配置,可以實現對Tomcat中各個元件的控制。

server.xml的整體結構如下:

1、server.xml檔案中的元素可以分為以下4類(1)頂層元素:和元素是整個配置檔案的根元素,元素則代表一個Engine元素以及一組與之相連的Connector元素。(2)聯結器:代表了外部客戶端傳送請求到特定Service的介面;同時也是外部客戶端從特定Service接收響應的介面。(3)容器:容器的功能是處理Connector接收進來的請求,併產生相應的響應。Engine、Host和Context都是容器,但它們不是平行的關係,而是父子關係:Engine包含Host,Host包含Context。一個Engine元件可以處理Service中的所有請求,一個Host元件可以處理發向一個特定虛擬主機的所有請求,一個Context元件可以處理一個特定Web應用的所有請求。(4)內嵌元件:可以內嵌到容器中的元件。實際上,Server、Service、Connector、Engine、Host和Context是最重要的最核心的Tomcat元件,其他元件都可以歸為內嵌元件。2、各個核心元件的作用、特點以及配置方式1)ServerServer元素在最頂層,代表整個Tomcat容器,因此它必須是server.xml中唯一一個最外層的元素。一個Server元素中可以有一個或多個Service元素。在第一部分的例子中,在最外層有一個元素,shutdown屬性表示關閉Server的指令;port屬性表示Server接收shutdown指令的埠號,設為-1可以禁掉該埠。2)ServiceService的作用,是在Connector和Engine外面包了一層,把它們組裝在一起,對外提供服務。一個Service可以包含多個Connector,但是隻能包含一個Engine;其中Connector的作用是從客戶端接收請求,Engine的作用是處理接收進來的請求。在第一部分的例子中,Server中包含一個名稱為“Catalina”的Service。實際上,Tomcat可以提供多個Service,不同的Service監聽不同的埠。3)ConnectorConnector的主要功能,是接收連線請求,建立Request和Response物件用於和請求端交換資料;然後分配執行緒讓Engine來處理這個請求,並把產生的Request和Response物件傳給Engine。透過配置Connector,可以控制請求Service的協議及埠號。Service可以配置兩個Connector。eg:配置兩個Connector(1)透過配置第1個Connector,客戶端可以透過8080埠號使用http協議訪問Tomcat。其中,protocol屬性規定了請求的協議,port規定了請求的埠號,redirectPort表示當強制要求https而請求是http時,重定向至埠號為8443的Connector,connectionTimeout表示連線的超時時間。在這個例子中,Tomcat監聽HTTP請求,使用的是8080埠,而不是正式的80埠;實際上,在正式的生產環境中,Tomcat也常常監聽8080埠,而不是80埠。這是因為在生產環境中,很少將Tomcat直接對外開放接收請求,而是在Tomcat和客戶端之間加一層代理伺服器(如nginx),用於請求的轉發、負載均衡、處理靜態檔案等;透過代理伺服器訪問Tomcat時,是在區域網中,因此一般仍使用8080埠。(2)透過配置第2個Connector,客戶端可以透過8009埠號使用AJP協議訪問Tomcat。是因為Tomcat可以用作Servlet/JSP容器,但是對靜態資源的處理速度較慢,不如Apache和IIS等HTTP伺服器;因此常常將Tomcat與Apache等整合,前者作Servlet容器,後者處理靜態資源,而AJP協議便負責Tomcat和Apache的連線。4)EngineEngine元件在Service元件中有且只有一個;Engine是Service元件中的請求處理元件。Engine元件從一個或多個Connector中接收請求並處理,並將完成的響應返回給Connector,最終傳遞給客戶端。eg:name屬性用於日誌和錯誤資訊,defaultHost屬性指定了預設的host名稱,當發往本機的請求指定的host名稱不存在時,一律使用defaultHost指定的host進行處理;因此,defaultHost的值,必須與Engine中的一個Host元件的name屬性值匹配。name屬性用於日誌和錯誤資訊,在整個Server中應該唯一。5)HostHost是Engine的子容器。Engine元件中可以內嵌1個或多個Host元件,每個Host元件代表Engine中的一個虛擬主機。Host元件至少有一個,且其中一個的name必須與Engine元件的defaultHost屬性相匹配。Host的作用:Host虛擬主機的作用,是執行多個Web應用(一個Context代表一個Web應用),並負責安裝、展開、啟動和結束每個Web應用。Host元件代表的虛擬主機,對應了伺服器中一個網路名實體(如”www.test.com”,或IP地址”116.25.25.25”);為了使使用者可以透過網路名連線Tomcat伺服器,這個名字應該在DNS伺服器上註冊。客戶端通常使用主機名來標識它們希望連線的伺服器;該主機名也會包含在HTTP請求頭中。Tomcat從HTTP頭中提取出主機名,尋找名稱匹配的主機。如果沒有匹配,請求將傳送至預設主機。因此預設主機不需要是在DNS伺服器中註冊的網路名,因為任何與所有Host名稱不匹配的請求,都會路由至預設主機。Host的引數:unpackWARs指定了是否將代表Web應用的WAR檔案解壓;如果為true,透過解壓後的檔案結構執行該Web應用,如果為false,直接使用WAR檔案執行Web應用。
Host的autoDeploy和appBase屬性,與Host內Web應用的自動部署有關;一個Engine中有且僅有一個Host元件的name屬性與Engine元件的defaultHost屬性相匹配Host元素內定義了Valve元件:不同的Valve有不同的特性,AccessLogValve記錄的日誌就是訪問日誌,每天的請求會寫到一個日誌檔案裡。AccessLogValve可以與Engine、Host或Context關聯;一個容器內可以建立多個Valve,而且Valve定義的次序也決定了它們生效的次序。Valve元件引數:className:規定了Valve的型別,是最重要的屬性;本例中,透過該屬性規定了這是一個AccessLogValve。
directory:指定日誌儲存的位置,本例中,日誌儲存在$TOMCAT_HOME/logs目錄下。
prefix:指定了日誌檔案的字首。
suffix:指定了日誌檔案的字尾。透過directory、prefix和suffix的配置,在$TOMCAT_HOME/logs目錄下,可以看到如下所示的日誌檔案。
pattern:指定記錄日誌的格式小結:pattern中一些值:
%h:遠端主機名或IP地址;如果有nginx等反向代理伺服器進行請求分發,該主機名/IP地址代表的是nginx,否則代表的是客戶端。後面遠端的含義與之類似,不再解釋。
%l:遠端邏輯使用者名稱,一律是”-”,可以忽略。
%u:授權的遠端使用者名稱,如果沒有,則是”-”。
%t:訪問的時間。
%r:請求的第一行,即請求方法(get/post等)、uri、及協議。
%s:響應狀態,200,404等等。
%b:響應的資料量,不包括請求頭,如果為0,則是””-。
%D:請求處理的時間(單位是毫秒)6)Context(靜態部署)Context元素代表在特定虛擬主機上執行的一個Web應用。每個Web應用基於WAR檔案,或WAR檔案解壓後對應的目錄

元素引數如下:

docBase:docBase指定了該Web應用使用的WAR包路徑,或應用目錄。靜態部署時,docBase可以在appBase目錄下,也可以不在;本例中,docBase不在appBase目錄下。 path:靜態部署時,可以顯式指定path屬性,但是仍然受到了嚴格的限制:只有當自動部署完全關閉(deployOnStartup和autoDeploy都為false)或docBase不在appBase中時,才可以設定path屬性。在本例中,docBase不在appBase中,因此path屬性可以設定。 reloadable屬性指示tomcat是否在執行時監控在WEB-INF/classes和WEB-INF/lib目錄下class檔案的改動。如果值為true,那麼當class檔案改動時,會觸發Web應用的重新載入。在開發環境下,reloadable設定為true便於除錯;但是在生產環境中設定為true會給伺服器帶來效能壓力,因此reloadable引數的預設值為false。

但是目前往往server.xml配置檔案中看不到Context元素的出現,因為Tomcat開啟了自動部署,Web應用沒有在server.xml中配置靜態部署,而是由Tomcat透過特定的規則自動部署。

Context是Host的子容器,每個Host中可以定義任意多的Context元素。 ==靜態部署與自動部署是可以共存的。在實際應用中,並不推薦使用靜態部署,因為server.xml 是不可動態重載入的資源,伺服器一旦啟動了以後,要修改這個檔案,就得重啟伺服器才能重新載入。而自動部署可以在Tomcat執行時透過定期的掃描來實現,不需要重啟伺服器。==

7)Listener

Listener(即監聽器)定義的元件,可以在特定事件發生時執行特定的操作;被監聽的事件通常是Tomcat的啟動和停止。監聽器需要配置的最重要的屬性是className,該屬性規定了監聽器的具體實現類,該類必須實現了org.apache.catalina.LifecycleListener介面。


下面依次介紹例子中配置的監聽器:

VersionLoggerListener:當Tomcat啟動時,該監聽器記錄Tomcat、Java和作業系統的資訊。該監聽器必須是配置的第一個監聽器。 AprLifecycleListener:Tomcat啟動時,檢查APR庫,如果存在則載入。APR,即Apache Portable Runtime,是Apache可移植執行庫,可以實現高可擴充套件性、高效能,以及與本地伺服器技術更好的整合。 JasperListener:在Web應用啟動之前初始化Jasper,Jasper是JSP引擎,把JVM不認識的JSP檔案解析成java檔案,然後編譯成class檔案供JVM使用。 JreMemoryLeakPreventionListener:與類載入器導致的記憶體洩露有關。 GlobalResourcesLifecycleListener:透過該監聽器,初始化< GlobalNamingResources>標籤中定義的全域性JNDI資源;如果沒有該監聽器,任何全域性資源都不能使用。< GlobalNamingResources>將在後文介紹。 ThreadLocalLeakPreventionListener:當Web應用因thread-local導致的記憶體洩露而要停止時,該監聽器會觸發執行緒池中執行緒的更新。當執行緒執行完任務被收回執行緒池時,活躍執行緒會一個一個的更新。只有當Web應用(即Context元素)的renewThreadsWhenStoppingContext屬性設定為true時,該監聽器才有效。

8)GlobalNamingResources與Realm

Realm提供了一種使用者密碼與web應用的對映關係,從而達到角色安全管理的作用。Realm的配置使用name為UserDatabase的資源實現。而該資源在Server元素中使用GlobalNamingResources配置,GlobalNamingResources元素定義了全域性資源,透過配置可以看出,該配置是透過讀取$TOMCAT_HOME/ conf/tomcat-users.xml實現的。