一:Tomcat核心元件及應用架構詳解 - tw511教學網
文章推薦指數: 80 %
Servlet 容器. Web 應用. 擴充套件機制. 一、Tomcat各元件認知. 2.Tomcat 各元件及關係. 二、Tomcat server.xml 設定詳解. 三、Tomcat 部署指令碼編寫 ...
技術文章»一:Tomcat核心元件及應用架構詳解
一:Tomcat核心元件及應用架構詳解
2021-05-2708:00:08
目錄
Web容器是什麼?
HTTP的本質
HTTP請求響應範例
Cookie和Session
Servlet規範
Servlet容器
Web應用
擴充套件機制
一、Tomcat各元件認知
2.Tomcat各元件及關係
二、Tomcatserver.xml設定詳解
三、Tomcat部署指令碼編寫
Web容器是什麼?
讓我們先來簡單回顧一下Web技術的發展歷史,可以幫助你理解Web容器的由來。
早期的Web應用主要用於瀏覽新聞等靜態頁面,HTTP伺服器(比如Apache、Nginx)向瀏覽器返回靜態HTML,瀏覽器負責解析HTML,將結果呈現給使用者。
隨著網際網路的發展,我們已經不滿足於僅僅瀏覽靜態頁面,還希望通過一些互動操作,來獲取動態結果,因此也就需要一些擴充套件機制能夠讓HTTP伺服器呼叫伺服器端程式。
於是Sun公司推出了Servlet技術。
你可以把Servlet簡單理解為執行在伺服器端的Java小程式,但是Servlet沒有main方法,不能獨立執行,因此必須把它部署到Servlet容器中,由容器來範例化並呼叫Servlet。
而Tomcat就是一個Servlet容器。
為了方便使用,它們也具有HTTP伺服器的功能,因此Tomcat就是一個「HTTP伺服器+Servlet容器」,我們也叫它們Web容器。
HTTP的本質
HTTP協定是瀏覽器與伺服器之間的資料傳送協定。
作為應用層協定,HTTP是基於TCP/IP協定來傳遞資料的(HTML檔案、圖片、查詢結果等),HTTP協定不涉及封包(Packet)傳輸,主要規定了使用者端和伺服器之間的通訊格式。
假如瀏覽器需要從遠端HTTP伺服器獲取一個HTML文字,在這個過程中,瀏覽器實際上要做兩件事情。
與伺服器建立Socket連線。
生成請求資料並通過Socket傳送出去。
HTTP請求響應範例
使用者在登陸頁面輸入使用者名稱和密碼,點選登陸後,瀏覽器發出了這樣的HTTP請求:
HTTP請求資料由三部分組成,分別是請求行、請求報頭、請求正文。
當這個HTTP請求資料到達Tomcat後,Tomcat會把HTTP請求資料位元組流解析成一個Request物件,這個Request物件封裝了HTTP所有的請求資訊。
接著Tomcat把這個Request物件交給Web應用去處理,處理完後得到一個Response物件,Tomcat會把這個Response物件轉成HTTP格式的響應資料並行送給瀏覽器。
HTTP的響應也是由三部分組成,分別是狀態行、響應報頭、報文主體。
同樣,我還以極客時間登陸請求的響應為例。
Cookie和Session
我們知道,HTTP協定有個特點是無狀態,請求與請求之間是沒有關係的。
這樣會出現一個很尷尬的問題:Web應用不知道你是誰。
因此HTTP協定需要一種技術讓請求與請求之間建立起聯絡,並且伺服器需要知道這個請求來自哪個使用者,於是Cookie技術出現了。
Cookie是HTTP報文的一個請求頭,Web應用可以將使用者的標識資訊或者其他一些資訊(使用者名稱等)儲存在Cookie中。
使用者經過驗證之後,每次HTTP請求報文中都包含Cookie,這樣伺服器讀取這個Cookie請求頭就知道使用者是誰了。
Cookie本質上就是一份儲存在使用者原生的檔案,裡面包含了每次請求中都需要傳遞的資訊。
由於Cookie以明文的方式儲存在本地,而Cookie中往往帶有使用者資訊,這樣就造成了非常大的安全隱患。
而Session的出現解決了這個問題,Session可以理解為伺服器端開闢的儲存空間,裡面儲存了使用者的狀態,使用者資訊以Session的形式儲存在伺服器端。
當使用者請求到來時,伺服器端可以把使用者的請求和使用者的Session對應起來。
那麼Session是怎麼和請求對應起來的呢?答案是通過Cookie,瀏覽器在Cookie中填充了一個SessionID之類的欄位用來標識請求。
具體工作過程是這樣的:伺服器在建立Session的同時,會為該Session生成唯一的SessionID,當瀏覽器再次傳送請求的時候,會將這個SessionID帶上,伺服器接受到請求之後就會依據SessionID找到相應的Session,找到Session後,就可以在Session中獲取或者新增內容了。
而這些內容只會儲存在伺服器中,發到使用者端的只有SessionID,這樣相對安全,也節省了網路流量,因為不需要在Cookie中儲存大量使用者資訊。
那麼Session在何時何地建立呢?當然還是在伺服器端程式執行的過程中建立的,不同語言實現的應用程式有不同的建立Session的方法。
在Java中,是Web應用程式在呼叫HttpServletRequest的getSession方法時,由Web容器(比如Tomcat)建立的。
Tomcat的Session管理器提供了多種持久化方案來儲存Session,通常會採用高效能的儲存方式,比如Redis,並且通過叢集部署的方式,防止單點故障,從而提升高可用。
同時,Session有過期時間,因此Tomcat會開啟後臺執行緒定期的輪詢,如果Session過期了就將Session失效。
Servlet規範
HTTP伺服器怎麼知道要呼叫哪個Java類的哪個方法呢。
最直接的做法是在HTTP伺服器程式碼裡寫一大堆ifelse邏輯判斷:如果是A請求就調X類的M1方法,如果是B請求就調Y類的M2方法。
但這樣做明顯有問題,因為HTTP伺服器的程式碼跟業務邏輯耦合在一起了,如果新加一個業務方法還要改HTTP伺服器的程式碼。
那該怎麼解決這個問題呢?我們知道,面向介面程式設計是解決耦合問題的法寶,於是有一夥人就定義了一個介面,各種業務類都必須實現這個介面,這個介面就叫Servlet介面,有時我們也把實現了Servlet介面的業務類叫作Servlet。
但是這裡還有一個問題,對於特定的請求,HTTP伺服器如何知道由哪個Servlet來處理呢?Servlet又是由誰來範例化呢?顯然HTTP伺服器不適合做這個工作,否則又和業務類耦合了。
於是,還是那夥人又發明了Servlet容器,Servlet容器用來載入和管理業務類。
HTTP伺服器不直接跟業務類打交道,而是把請求交給Servlet容器去處理,Servlet容器會將請求轉發到具體的Servlet,如果這個Servlet還沒建立,就載入並範例化這個Servlet,然後呼叫這個Servlet的介面方法。
因此Servlet介面其實是Servlet容器跟具體業務類之間的介面。
下面我們通過一張圖來加深理解。
Servlet介面和Servlet容器這一整套規範叫作Servlet規範。
Tomcat和Jetty都按照Servlet規範的要求實現了Servlet容器,同時它們也具有HTTP伺服器的功能。
作為Java程式設計師,如果我們要實現新的業務功能,只需要實現一個Servlet,並把它註冊到Tomcat(Servlet容器)中,剩下的事情就由Tomcat幫我們處理了。
Servlet介面定義了下面五個方法:
publicinterfaceServlet{
voidinit(ServletConfigconfig)throwsServletException;
ServletConfiggetServletConfig();
voidservice(ServletRequestreq,ServletResponseres)throwsServletException,IOException;
StringgetServletInfo();
voiddestroy();
}
其中最重要是的service方法,具體業務類在這個方法裡實現處理邏輯。
這個方法有兩個引數:ServletRequest和ServletResponse。
ServletRequest用來封裝請求資訊,ServletResponse用來封裝響應資訊,因此本質上這兩個類是對通訊協定的封裝。
HTTP協定中的請求和響應就是對應了HttpServletRequest和HttpServletResponse這兩個類。
你可以通過HttpServletRequest來獲取所有請求相關的資訊,包括請求路徑、Cookie、HTTP頭、請求引數等。
此外,我們還可以通過HttpServletRequest來建立和獲取Session。
而HttpServletResponse是用來封裝HTTP響應的。
你可以看到介面中還有兩個跟生命週期有關的方法init和destroy,這是一個比較貼心的設計,Servlet容器在載入Servlet類的時候會呼叫init方法,在解除安裝的時候會呼叫destroy方法。
我們可能會在init方法裡初始化一些資源,並在destroy方法裡釋放這些資源,比如SpringMVC中的DispatcherServlet,就是在init方法裡建立了自己的Spring容器。
你還會注意到ServletConfig這個類,ServletConfig的作用就是封裝Servlet的初始化引數。
你可以在web.xml給Servlet設定引數,並在程式裡通過getServletConfig方法拿到這些引數。
我們知道,有介面一般就有抽象類,抽象類用來實現介面和封裝通用的邏輯,因此Servlet規範提供了GenericServlet抽象類,我們可以通過擴充套件它來實現Servlet。
雖然Servlet規範並不在乎通訊協定是什麼,但是大多數的Servlet都是在HTTP環境中處理的,因此Servet規範還提供了HttpServlet來繼承GenericServlet,並且加入了HTTP特性。
這樣我們通過繼承HttpServlet類來實現自己的Servlet,只需要重寫兩個方法:doGet和doPost。
Servlet容器
當客戶請求某個資源時,HTTP伺服器會用一個ServletRequest物件把客戶的請求資訊封裝起來,然後呼叫Servlet容器的service方法,Servlet容器拿到請求後,根據請求的URL和Servlet的對映關係,找到相應的Servlet,如果Servlet還沒有被載入,就用反射機制建立這個Servlet,並呼叫Servlet的init方法來完成初始化,接著呼叫Servlet的service方法來處理請求,把ServletResponse物件返回給HTTP伺服器,HTTP伺服器會把響應傳送給使用者端
Web應用
Servlet容器會範例化和呼叫Servlet,那Servlet是怎麼註冊到Servlet容器中的呢?一般來說,我們是以Web應用程式的方式來部署Servlet的,而根據Servlet規範,Web應用程式有一定的目錄結構,在這個目錄下分別放置了Servlet的類檔案、組態檔以及靜態資源,Servlet容器通過讀取組態檔,就能找到並載入Servlet。
Web應用的目錄結構大概是下面這樣的:
|-MyWebApp
|-WEB-INF/web.xml--組態檔,用來設定Servlet等
|-WEB-INF/lib/--存放Web應用所需各種JAR包
|-WEB-INF/classes/--存放你的應用類,比如Servlet類
|-META-INF/--目錄存放工程的一些資訊
Servlet規範裡定義了ServletContext這個介面來對應一個Web應用。
Web應用部署好後,Servlet容器在啟動時會載入Web應用,併為每個Web應用建立唯一的ServletContext物件。
你可以把ServletContext看成是一個全域性物件,一個Web應用可能有多個Servlet,這些Servlet可以通過全域性的ServletContext來共用資料,這些資料包括Web應用的初始化引數、Web應用目錄下的檔案資源等。
由於ServletContext持有所有Servlet範例,你還可以通過它來實現Servlet請求的轉發。
擴充套件機制
引入了Servlet規範後,你不需要關心Socket網路通訊、不需要關心HTTP協定,也不需要關心你的業務類是如何被範例化和呼叫的,因為這些都被Servlet規範標準化了,你只要關心怎麼實現的你的業務邏輯。
這對於程式設計師來說是件好事,但也有不方便的一面。
所謂規範就是說大家都要遵守,就會千篇一律,但是如果這個規範不能滿足你的業務的個性化需求,就有問題了,因此設計一個規範或者一箇中介軟體,要充分考慮到可延伸性。
Servlet規範提供了兩種擴充套件機制:Filter和Listener。
Filter是過濾器,這個介面允許你對請求和響應做一些統一的客製化化處理,比如你可以根據請求的頻率來限制存取,或者根據國家地區的不同來修改響應內容。
過濾器的工作原理是這樣的:Web應用部署完成後,Servlet容器需要範例化Filter並把Filter連結成一個FilterChain。
當請求進來時,獲取第一個Filter並呼叫doFilter方法,doFilter方法負責呼叫這個FilterChain中的下一個Filter。
Listener是監聽器,這是另一種擴充套件機制。
當Web應用在Servlet容器中執行時,Servlet容器內部會不斷的發生各種事件,如Web應用的啟動和停止、使用者請求到達等。
Servlet容器提供了一些預設的監聽器來監聽這些事件,當事件發生時,Servlet容器會負責呼叫監聽器的方法。
當然,你可以定義自己的監聽器去監聽你感興趣的事件,將監聽器設定在web.xml中。
比如Spring就實現了自己的監聽器,來監聽ServletContext的啟動事件,目的是當Servlet容器啟動時,建立並初始化全域性的Spring容器。
Tomcat下載地址:https://tomcat.apache.org/download-80.cgi
/bin:存放Windows或Linux平臺上啟動和關閉Tomcat的指令碼檔案。
/conf:存放Tomcat的各種全域性組態檔,其中最重要的是server.xml。
/lib:存放Tomcat以及所有Web應用都可以存取的JAR檔案。
/logs:存放Tomcat執行時產生的紀錄檔檔案。
/work:存放JSP編譯後產生的Class檔案。
/webapps:Tomcat的Web應用目錄,預設情況下把Web應用放在這個目錄下。
開啟Tomcat的紀錄檔目錄,也就是Tomcat安裝目錄下的logs目錄。
Tomcat的紀錄檔資訊分為兩類:一是執行紀錄檔,它主要記錄執行過程中的一些資訊,尤其是一些異常錯誤紀錄檔資訊;二是存取紀錄檔,它記錄存取的時間、IP地址、存取的路徑等相關資訊。
catalina.***.log主要是記錄Tomcat啟動過程的資訊,在這個檔案可以看到啟動的JVM引數以及作業系統等紀錄檔資訊。
catalina.out是Tomcat的標準輸出(stdout)和標準錯誤(stderr),這是在Tomcat的啟動指令碼裡指定的,如果沒有修改的話stdout和stderr會重定向到這裡。
所以在這個檔案裡可以看到我們在MyServlet.java程式裡列印出來的資訊localhost.**.log主要記錄Web應用在初始化過程中遇到的未處理的異常,會被Tomcat捕獲而輸出這個紀錄檔檔案。
localhost_access_log.**.txt存放存取Tomcat的請求紀錄檔,包括IP地址以及請求的路徑、時間、請求協定以及狀態碼等資訊。
manager.***.log/host-manager.***.log存放Tomcat自帶的Manager專案的紀錄檔資訊。
概要:
Tomcat各核心元件認知server.xml設定詳解
一、Tomcat各元件認知
知識點:
Tomcat架構說明Tomcat元件及關係詳情介紹Tomcat啟動引數說明Tomcat架構說明
Tomcat是一個基於JAVA的WEB容器,其實現了JAVAEE中的Servlet與jsp規範,與Nginxapache伺服器不同在於一般用於動態請求處理。
在架構設計上採用面向元件的方式設計。
即整體功能是通過元件的方式拼裝完成。
另外每個元件都可以被替換以保證靈活性。
2.Tomcat各元件及關係
Server和ServiceConnector聯結器
HTTP1.1SSLhttpsAJP( ApacheJServProtocol)apache私有協定,用於apache反向代理Tomcat
Container
Engine引擎catalinaHost虛擬機器器基於域名分發請求Context隔離各個WEB應用每個Context的ClassLoader都是獨立
Component
Manager(管理器)logger(紀錄檔管理)loader(載入器)pipeline(管道)valve(管道中的閥)
二、Tomcatserver.xml設定詳解
server
root元素:server的頂級設定主要屬性:port:執行關閉命令的埠號shutdown:關閉命令
演示shutdown的用法 #基於telent執行SHUTDOWN命令即可關閉(必須大寫)telnet127.0.0.18005SHUTDOWN
service
服務:將多個connector與一個Engine組合成一個服務,可以設定多個服務。
Connector
聯結器:用於接收指定協定下的連線並指定給唯一的Engine進行處理。
主要屬性:
protocol監聽的協定,預設是http/1.1port指定伺服器端要建立的埠號minSpareThreads伺服器啟動時建立的處理請求的執行緒數maxThreads最大可以建立的處理請求的執行緒數enableLookups如果為true,則可以通過呼叫request.getRemoteHost()進行DNS查詢來得到遠端使用者端的實際主機名,若為false則不進行DNS查詢,而是返回其ip地址redirectPort指定伺服器正在處理http請求時收到了一個SSL傳輸請求後重定向的埠號acceptCount指定當所有可以使用的處理請求的執行緒數都被使用時,可以放到處理佇列中的請求數,超過這個數的請求將不予處理connectionTimeout指定超時的時間數(以毫秒為單位)SSLEnabled是否開啟sll驗證,在Https存取時需要開啟。
生成證書:keytool-genkey-v-aliastestKey-keyalgRSA-validity3650-keystoreD:\test.keystore[] 演示設定多個Connector
一個service中只能設定一個Engine。
主要屬性:name引擎名稱defaultHost預設host
Host
虛擬機器器:基於域名匹配至指定虛擬機器器。
類似於nginx當中的server,預設的虛擬機器器是localhost.主要屬性:
演示設定多個Host
相互隔離,以免造成ClassPath衝突。
主要屬性:
演示設定多個Context
以下即為一個存取紀錄檔的Valve
執行starut.bat指令碼啟動。
啟動過程中war包會被自動解壓裝載。
但是我們在Eclipse或idea中啟動WEB專案的時候也是把War包複雜至webapps目錄解壓嗎?顯然不是,其真正做法是在Tomcat程式檔案之外建立了一個部署目錄,在一般生產環境中也是這麼做的即:Tomcat程式目錄和部署目錄分開。
我們只需要在啟動時指定CATALINA_HOME與CATALINA_BASE引數即可實現。
| 啟動引數 | 描述說明 ||:----|:----||JAVA_OPTS|jvm啟動引數,設定記憶體編碼等-Xms100m-Xmx200m-Dfile.encoding=UTF-8||JAVA_HOME|指定jdk目錄,如果未設定從java環境變數當中去找。
||CATALINA_HOME|Tomcat程式根目錄||CATALINA_BASE|應用部署目錄,預設為$CATALINA_HOME||CATALINA_OUT|應用紀錄檔輸出目錄:預設$CATALINA_BASE/log||CATALINA_TMPDIR|應用臨時目錄:預設:$CATALINA_BASE/temp|
可以編寫一個指令碼來實現自定義設定:
ln-s/home/wukong/apache-tomcat-8.5.56apache-tomcat
更新啟動指令碼
#!/bin/bash
exportJAVA_OPTS="-Xms100m-Xmx200m"
exportCATALINA_HOME=/home/wukong/apache-tomcat
exportCATALINA_BASE="`pwd`"
case$1in
start)
$CATALINA_HOME/bin/catalina.shstart
echostartsuccess!!
;;
stop)
$CATALINA_HOME/bin/catalina.shstop
echostopsuccess!!
;;
restart)
$CATALINA_HOME/bin/catalina.shstop
echostopsuccess!!
sleep3
$CATALINA_HOME/bin/catalina.shstart
echostartsuccess!!
;;
version)
$CATALINA_HOME/bin/catalina.shversion
;;
configtest)
$CATALINA_HOME/bin/catalina.shconfigtest
;;
esac
exit0
docker啟動tomcat
dockerrun-id--name=test_tomcat-eJAVA_OPTS='-Xmx128m'-p8888:8080-v/usr/local/tuling-project/tomcat-test/webapps:/usr/local/tomcat/webapps-v/usr/local/tuling-project/tomcat-test/logs:/usr/local/tomcat/logs-v/usr/local/tuling-project/tomcat-test/conf:/usr/local/tomcat/conf--privileged=truetomcat:8
原始碼構建
下載地址:https://tomcat.apache.org/download-80.cgi
設定
1.解壓原始碼apache-tomcat-8.5.57-src
2.apache-tomcat-8.5.57-src目錄下新增pom檔案
延伸文章資訊
- 1Tomcat的下載與安裝 - IT人
啟動的命令符不能關!,不然伺服器也會終止! 在這裡插入圖片描述. 相關文章. Linux配置JavaEE環境Linux中安裝JDK、Tomcat、mysql 設定Tomcat ...
- 2Java JSP架站- Tomcat Apache Eclipse 設定 - 進度條
1. 下載Eclipse · 2. 之後下載JAVA jdk · 3. 下載"Apache Tomcat" · 4. 設定Eclipse · 5. 安裝Tomcat Server · 6. 改變...
- 3Day29 Spring Boot發佈篇-認識tomcat(下) - iT 邦幫忙
tomcat是一個開源Java Servlet 容器(Container),它與Apache都是網路伺服器, ... conf :tomcat伺服器設定檔皆在此資料夾內; log :tomcat...
- 4一:Tomcat核心元件及應用架構詳解 - tw511教學網
Servlet 容器. Web 應用. 擴充套件機制. 一、Tomcat各元件認知. 2.Tomcat 各元件及關係. 二、Tomcat server.xml 設定詳解. 三、Tomcat 部署...
- 5Apache Tomcat 完整安裝教學、附更改通訊埠& 虛實位址對應 ...
△檔案總管裡可以找到「Apache Tomcat 9.0 Tomcat9」的「Configure Tomcat」,這就是控制畫面,可以在此設定是否開機自動啟動(當然!這將消耗電腦資源) ...