之前的兩篇文章探討了兩種HTTP Server的工作原理,本篇講解Java開發中最常使用的一款應用web服務器Tomcat。有過開發經驗的人應該了解因為Apache,Nginx等HTTP Server只能解析靜態資源,不能解析Java Web開發中使用的Servlet和JSP,因此需要有一款能夠解析Java語言的服務器使得Java Web項目能夠正常運行。Tomcat作為Java Web項目的容器將項目部署到其webapps目錄下即可運行。
Tomcat工作原理
基于Java的Web 應用程序是 servlet、JSP 頁面、靜態頁面、類和其他資源的集合,它們可以用標準方式打包,并運行在來自多個供應商的多個容器。Web 應用程序存在于結構化層次結構的目錄中,該層次結構是由 Java Servlet 規范定義的。Web 應用程序的根目錄包含直接存儲或存儲在子文件夾中的所有公共資源,比如圖像、HTML 頁面等。構成:Web應用由Web組件(一組Java類庫)、html文件,靜態資源文件(如圖像)、幫助類和庫組成。
Tomcat Server的組成部分
①Server
一個英文的比較官方的定義
A Server element represents the entire Catalina servlet container. (Singleton)
大致意思就是Server是一個Servlet容器,有且只有一個。Server起管理者的作用,管理Tomcat的其他組件。
②Service
A Service element represents the combination of one or more Connector components that share a single Engine
Service是這樣一個集合:它由共享同的一個Engine一個或者多個Connector組成,負責處理所有Connector所獲得的客戶請求。
③Connector
一個Connector將在某個指定端口上偵聽客戶請求,并將獲得的請求交給Engine來處理,從Engine處獲得回應并返回客戶。
Tomcat包含兩類Connector,分別是Coyote Http/1.1 Connector,默認監聽8080端口,直接偵聽來自browser的http請求。另一類是Coyote JK2 Connector,監聽8009端口,偵聽來自其它WebServer的請求。如來自Apache或者Nginx的請求。
④Engine
The Engine element represents the entire request processing machinery associated with a particular Service
It receives and processes all requests from one or more Connectors
and returns the completed response to the Connector for ultimate transmission back to the client
從上面這段話得知Engine是處理請求并返回響應的中樞組件,且可以關聯一個或多個Connector。Engine下可以配置多個虛擬主機Virtual Host,每個虛擬主機都有一個域名。當Engine獲得一個請求時,它把該請求匹配到某個Host上,然后把該請求交給該Host來處理。Engine有一個默認虛擬主機,當請求無法匹配到任何一個Host上的時候,將交給該默認Host來處理。如果出現匹配不到的情況,則交由localhost處理。
⑤Host
指一個Virtual Host,虛擬主機和某個網絡域名Domain Name相匹配。每個虛擬主機下都可以部署(deploy)一個或者多個Web App,每個Web App對應于一個Context,有一個Context path。當Host獲得一個請求時,將把該請求匹配到某個Context上,然后把該請求交給該Context來處理。
⑥Context
一個Context對應于一個Web Application,一個Web Application由一個或者多個Servlet組成。Context在創建的時候將根據配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml載入Servlet類。當Context獲得請求時,將在自己的映射表(即web.xml中的一眾mapping)中尋找相匹配的Servlet類,如果找到,則執行該類,獲得請求的回應,并返回。
Tomcat Server處理一個http請求的過程
以http://localhost:8080/mypro/index.jsp的請求過程為例
①請求被發送到本機端口8080,被在那里偵聽的Coyote HTTP/1.1 Connector獲得。
②Connector把該請求交給它所在的Service的Engine來處理,并等待來自Engine的回應。
③ Engine獲得請求localhost/mypro/index.jsp,匹配它所擁有的所有虛擬主機Host。
④Engine匹配到名為localhost的Host。
⑤localhost Host獲得請求/mypro/index.jsp,匹配它所擁有的所有Context。匹配到路徑為/mypro的Context。
⑥Context獲得請求/index.jsp,在它的mapping table中尋找對應的servlet。Context匹配到URL PATTERN為*.jsp的Servlet。
⑦構造HttpServletRequest對象和HttpServletResponse對象,作為參數調用Servlet的doGet或doPost方法并把執行完了之后的HttpServletResponse對象返回給Host。
⑧Host把HttpServletResponse對象返回給Engine。
⑨Engine把HttpServletResponse對象返回給Connector。
⑩Connector把HttpServletResponse對象返回給客戶browser。
Tomcat的工作流程講到這里,之后將有專門的文章講解HTTP Server如何與Application Server相結合使用。將以Tomcat和Nginx整合使用為例。