在介紹Tomcat以前咱們再來好好回顧一下Servlet和JSP前端
Servlet是一種CGI技術,能實現讓Java開發動態的Web資源,並經過CGI技術與前端的Web服務器進行通訊,但其對HTML文檔的定義都要有JAVA程序來實現,任何靜態資源以發生修改都要從新編譯整個Java頁面程序,很是的麻煩,而且Java程序員必須瞭解前端HTML的展現方式java
servlet也能夠被認爲是服務器端的applet。servlet被Web服務器加載和執行,就如同applet被瀏覽器加載和執行同樣。servlet從客戶端(經過Web服務器)接收請求,執行某種做業,而後返回結果。使用servlet的基本流程以下:程序員
1.客戶端經過HTTP提出請求.web
2.Web服務器接收該請求並將其發給servlet。若是這個servlet還沒有被加載,Web服務器將把它加載到 Java虛擬機而且執行它。
數據庫
3.servlet將接收該HTTP請求並執行某種處理。apache
4.servlet將向Web服務器返回應答。後端
5.Web服務器將從servlet收到的應答發送給客戶端。瀏覽器
因爲servlet是在服務器上執行,一般與applet相關的安全性的問題並不需實現。要注意的是Web瀏覽器並不直接和servlet通訊,servlet通常是由前端Web服務器加載和執行的;而servlet是用Java編寫的,因此servlet編寫一次就能夠在任何平臺運行(write once,run anywhere)。tomcat
JSP是一種腳本語言,它能夠實現將Java程序以標籤<% %>的形式嵌入到HTML文檔中,這樣極大的方便了程序的編譯和修改(Servlet的程序一發生修改(那怕是HTML靜態資源修改)就要從新編譯整個Java程序頁面),JSP修改後能夠當即看到結果,不須要手工編譯,JSP引擎會來作這些工做;而Servelt卻須要編譯,從新啓動Servlet引擎等一系列動做安全
可是JSP程序(通常爲.jsp結尾)要被執行必須先被轉譯(如Jasper)爲.java的源代碼,.java再由編譯器編譯爲.class類,而後在JVM中進行類加載、解釋才能執行
總之相對於Servlet來講,JSP能夠方便的讓Java與HTML進行結合,讓程序員能夠很方便的實如今HTML靜態文檔中加入或者修改Java編寫的動態內容,這也能夠說是Servlet和JSP惟一區別,其餘區別是在不大
Tomcat 服務器是一個免費的開放源代碼的Web應用服務器,屬於輕量級應用服務器,在中小型系統和併發訪問用戶不是不少的場合下被廣泛使用,是開發和調試JSP 程序的首選;通常來講以JSP格式開發的網站,幾乎都用Tomcat來做爲Java的應用程序服務器。Tomcat不嚴格來講的話就是一個Web Container(具備JVM,Jasper的功能,能夠直接對.jsp程序進行處理執行),可讓JSP編寫的動態web資源在Tomcat中運行,並將運行結果直接響應給client或者交給前端web server再響應給client
Tomcat的集羣通常都是前端由Apache做爲代理服務器,將用戶的.jsp請求所有轉發給位於後端的Tomcat進行處理,當配置正確時,Apache 爲HTML頁面服務,而Tomcat 實際上運行JSP 頁面和Servlet。另外,Tomcat和IIS等Web服務器同樣,具備處理HTML頁面的功能,另外它仍是一個Servlet和JSP容器,獨立的Servlet容器是Tomcat的默認模式。不過,Tomcat處理靜態HTML的能力不如Apache服務器。目前Tomcat最新版本爲9.0。
Tomcat的組件構成如圖
Tomcat的架構:
Tomcat 6支持Servlet 2.5和JSP 2.1的規範,它由一組嵌套的層次和組件組成,通常可分爲如下四類:
1.頂級組件:位於配置層次的頂級,而且彼此間有着嚴格的對應關係;Server、Service
2.鏈接器:鏈接客戶端(能夠是瀏覽器或Web服務器)請求至Servlet容器,
3.容器:包含一組其它組件;Engine、Host、Context
4.被嵌套的組件:位於一個容器當中,但不能包含其它組件;
各常見組件:
一、服務器(server):Tomcat的一個實例,一般一個JVM只能包含一個Tomcat實例;所以,一臺物理服務器上能夠在啓動多個JVM的狀況下在每個JVM中啓動一個Tomcat實例,每一個實例分屬於一個獨立的管理端口。這是一個頂級組件。
二、服務(service):一個服務組件一般包含一個引擎和與此引擎相關聯的一個或多個鏈接器。給服務命名能夠方便管理員在日誌文件中識別不一樣服務產生的日誌。一個server能夠包含多個service組件,但一般情下只爲一個service指派一個server。
鏈接器類組件:
三、鏈接器(connectors):負責鏈接客戶端(能夠是瀏覽器或Web服務器)請求至Servlet容器內的Web應用程序,一般指的是接收客戶發來請求的位置及服務器端分配的端口。默認端口一般是HTTP協議的8080,管理員也能夠根據本身的須要改變此端口。一個引擎能夠配置多個鏈接器,但這些鏈接器必須使用不一樣的端口。默認的鏈接器是基於HTTP/1.1的Coyote。同時,Tomcat也支持AJP、JServ和JK2鏈接器。
容器類組件:
四、引擎(Engine):引擎一般是指處理請求的Servlet引擎組件,即Catalina Servlet引擎,它檢查每個請求的HTTP首部信息以辨別此請求應該發往哪一個host或context,並將請求處理後的結果返回的相應的客戶端。嚴格意義上來講,容器沒必要非得經過引擎來實現,它也能夠是隻是一個容器。若是Tomcat被配置成爲獨立服務器,默認引擎就是已經定義好的引擎。而若是Tomcat被配置爲Apache Web服務器的提供Servlet功能的後端,默認引擎將被忽略,由於Web服務器自身就能肯定將用戶請求發往何處。一個引擎能夠包含多個host組件。
五、主機(Host):主機組件相似於Apache中的虛擬主機,但在Tomcat中只支持基於FQDN的「虛擬主機」。一個引擎至少要包含一個主機組件,但當引擎有多個Host時,請求到達引擎要決定發往哪一個HOST或者用戶請求了一個不存在的主機,因此這時通常要爲引擎指定一個默認的虛擬主機;每個虛擬主機均可以是一個獨立的網站。
六、上下文(Context):Context組件是最內層次的組件,它表示Web應用程序自己。配置一個Context最主要的是指定Web應用程序的根目錄,以便Servlet容器可以將用戶請求發往正確的位置。Context組件也可包含自定義的錯誤頁,以實如今用戶訪問發生錯誤時提供友好的提示信息;每一個context均可以單獨部署一個應用程序。
容器類組件:Engine、Host、Context
頂級組件:Server、Service
一個Service內只能有一個Engine,但能夠將一個或多個Connector(鏈接器)關聯到Engine上,一個Engine內能夠有多個Host,一個Host內能夠有多個Context
此外還有其餘被嵌套類(nested)組件:
這類組件一般包含於容器類組件中以提供具備管理功能的服務,它們不能包含其它組件,但有些卻能夠由不一樣層次的容器各自配置。
七、閥門(Valve):用來攔截請求並在將其轉至目標以前進行某種處理操做,相似於Servlet規範中定義的過濾器。Valve能夠定義在任何容器類的組件中。Valve常被用來記錄客戶端請求、客戶端IP地址和服務器等信息,這種處理技術一般被稱做請求轉儲(request dumping)。請求轉儲valve記錄請求客戶端請求數據包中的HTTP首部信息和cookie信息文件中,響應轉儲valve則記錄響應數據包首部信息和cookie信息至文件中。
八、日誌記錄器(Logger):用於記錄組件內部的狀態信息,可被用於除Context以外的任何容器中。日誌記錄的功能可被繼承,所以,一個引擎級別的Logger將會記錄引擎內部全部組件相關的信息,除非某內部組件定義了本身的Logger組件。
九、領域(Realm):用於用戶的認證和受權;在配置一個應用程序時,管理員能夠爲每一個資源或資源組定義角色及權限,而這些訪問控制功能的生效須要經過Realm來實現。Realm的認證能夠基於文本文件、數據庫表、LDAP服務等來實現。Realm的效用會遍佈整個引擎或頂級容器,所以,一個容器內的全部應用程序將共享用戶資源。同時,Realm能夠被其所在組件的子組件繼承,也能夠被子組件中定義的Realm所覆蓋。
Tomcat鏈接器架構:
基於Apache作爲Tomcat前端的架構來說,Apache經過mod_jk、mod_jk2或mod_proxy模塊與後端的Tomcat進行數據交換。而對Tomcat來講,每一個Web容器實例都有一個Java語言開發的鏈接器模塊組件,在Tomcat6中,這個鏈接器是org.apache.catalina.Connector類。這個類的構造器能夠構造兩種類別的鏈接器:HTTP/1.1負責響應基於HTTP/HTTPS協議的請求,AJP/1.3負責響應基於AJP的請求。但能夠簡單地經過在server.xml配置文件中實現鏈接器的建立,但建立時所使用的類根據系統是支持APR(Apache Portable Runtime)而有所不一樣。
APR是附加在提供了通用和標準API的操做系統之上一個通信層的本地庫的集合,它可以爲使用了APR的應用程序在與Apache通訊時提供較好伸縮能力時帶去平衡效用。
同時,須要說明的是,mod_jk2模塊目前已經再也不被支持了,mod_jk模塊目前還apache被支持,但其項目活躍度已經大大下降。所以,目前更經常使用 的方式是使用mod_proxy模塊。
若是支持APR:
一、HTTP/1.1:org.apache.cotote.http11.Http11AprProtocol
二、AJP/1.3:org.apache.coyote.ajp.AjpAprProtocol
若是不支持APR:
HTTP/1.1: org.apache.coyote.http11.Http11Protocol
AJP/1.3: org.apache.jk.server.JkCoyoteHandler
鏈接器協議:
Tomcat的Web服務器鏈接器支持兩種協議:AJP和HTTP,它們均定義了以二進制格式在Web服務器和Tomcat之間進行數據傳輸,並提供相應的控制命令。
AJP(Apache JServ Protocol)協議:
若是Tomcat的集羣前端是Apache依據本身的proxy_mod模塊做爲反向代理,則Apache能夠將前端的http請求以AJP協議發送給後端的Tomcat,AJP協議是基於二進制的格式在Web服務器和Tomcat之間傳輸數據
HTTP協議:如過Tomcat集羣的前端是由Nginx實現的反向代理,則其是使用HTTP或HTTPS協議在Web服務器和Tomcat之間創建通訊,此時,Tomcat就是一個徹底功能的HTTP服務器,它須要監聽在某端口上以接收來自於商前服務器的請求。
其使用Http協議轉發請求效率不如AJP的二進制格式,因此通常推薦Tomcat集羣的前端爲Apache,何況Apache與Tomcat都是ASF(Apache Software Foundation)出品的開源軟件。
Tomcat 工做模式
(1).獨立的Servlet容器
Tomcat 的默認工做模式,做爲獨立的Servlet容器,是內置在Web服務器中的一部分,是指使用基於JAVA的Web服務器的情形。其餘兩種方式是TOMCAT與其餘服務器集成的方式。
(2).進程內的Servlet容器
Servlet容器做爲Web服務器的插件和JAVA容器的實現。Web服務器的插件在內部地址空間打開一個JVM(JAVA VIRTUAL MACHINE)使JAVA容器得以在內部運行。若有某個須要調用Servlet的請求,插件將取得對此請求的控制並將它傳遞(使用JNI)給JAVA容器。進程內的容器對於多線程、單進程的服務器很是適合,而且提供了很好的運行速度,只是伸縮性有所不足。
注,JNI是JAVA NATIVE INTERFACE的縮寫,是JAVA本地調用接口,經過JNI,JAVA程序能夠和其餘語言編寫的本地程序進行通訊。
(3).進程外的Servlet容器
Servlet容器運行於Web服務器以外的地址空間,而且做爲Web服務器的插件和JVM使用IPC(如TCP/IP)進行通訊。進程外容器的反應時間不如進程內的容器,但有較好的伸縮性、穩定性等性能。
IPC INTERPROCESS COMMUNICATION(進程間通訊)的簡寫,它是實現進程間通訊的一種技術。
6.Tomcat各組件之間的關係
Tomcat是一個基於組件的服務器,它的構成組件都是可配置的,其中最外層的給件是CATALINA SERVLET容器,其餘的組件按照必定的格式要求配置在這個頂層容器中。Tomcat的各個組件是server.xml文件中配置的,Tomcat服務器默認狀況下對各類組件都有默認的實現,server.xml是Tomcat的核心配置文件,描述了Tomcat各個組件之間的關係
<Server> 頂層組件,表明一個服務器
<Service> 頂層組件,是Connector的集合,一個service只能有一個Engine
<Connectior/> 鏈接器,多個鏈接器能夠關聯到同一個Engine
<Engine> 容器類組件,爲特定的Service組件處理全部客戶請求,可包含多個Host
<Host> 容器類組件,爲特定的虛擬主機處理全部客戶請求
<Context>容器類組件,爲特定的WEB應用處理全部客戶請求
</Context>
</Host>
</Engine>
</Service>
</Server>
Tomcat中真正處理客戶請求與生成響應的三個組件是Engine 、Host、 Context。
以下圖爲Tomcat對用戶請求的處理及個組件的關係圖: