主頁 > 知識(shí)庫 > Tomcat核心組件及應(yīng)用架構(gòu)詳解

Tomcat核心組件及應(yīng)用架構(gòu)詳解

熱門標(biāo)簽:河南防封號(hào)電銷機(jī)器人是什么 怎么找到?jīng)]有地圖標(biāo)注的店 10086外包用的什么外呼系統(tǒng) 宿城區(qū)電話機(jī)器人找哪家 麗江真人語音電話外呼系統(tǒng) 打400電話怎么辦理收費(fèi) 400電話辦理介紹信 福州企業(yè)電銷機(jī)器人排名 上海申請(qǐng)高400開頭的電話

Web 容器是什么?

讓我們先來簡單回顧一下 Web 技術(shù)的發(fā)展歷史,可以幫助你理解 Web 容器的由來。

早期的 Web 應(yīng)用主要用于瀏覽新聞等靜態(tài)頁面,HTTP 服務(wù)器(比如 Apache、Nginx)向?yàn)g覽器返回靜態(tài) HTML,瀏覽器負(fù)責(zé)解析 HTML,將結(jié)果呈現(xiàn)給用戶。

隨著互聯(lián)網(wǎng)的發(fā)展,我們已經(jīng)不滿足于僅僅瀏覽靜態(tài)頁面,還希望通過一些交互操作,來獲取動(dòng)態(tài)結(jié)果,因此也就需要一些擴(kuò)展機(jī)制能夠讓 HTTP 服務(wù)器調(diào)用服務(wù)端程序。

于是 Sun 公司推出了 Servlet 技術(shù)。你可以把 Servlet 簡單理解為運(yùn)行在服務(wù)端的 Java 小程序,但是 Servlet 沒有 main 方法,不能獨(dú)立運(yùn)行,因此必須把它部署到 Servlet 容器中,由容器來實(shí)例化并調(diào)用 Servlet。

而 Tomcat 就是一個(gè) Servlet 容器。為了方便使用,它們也具有 HTTP 服務(wù)器的功能,因此 Tomcat 就是一個(gè)“HTTP 服務(wù)器 + Servlet 容器”,我們也叫它們 Web 容器。

HTTP 的本質(zhì)

HTTP 協(xié)議是瀏覽器與服務(wù)器之間的數(shù)據(jù)傳送協(xié)議。作為應(yīng)用層協(xié)議,HTTP 是基于 TCP/IP 協(xié)議來傳遞數(shù)據(jù)的(HTML 文件、圖片、查詢結(jié)果等),HTTP 協(xié)議不涉及數(shù)據(jù)包(Packet)傳輸,主要規(guī)定了客戶端和服務(wù)器之間的通信格式。

假如瀏覽器需要從遠(yuǎn)程 HTTP 服務(wù)器獲取一個(gè) HTML 文本,在這個(gè)過程中,瀏覽器實(shí)際上要做兩件事情。

  • 與服務(wù)器建立 Socket 連接。
  • 生成請(qǐng)求數(shù)據(jù)并通過 Socket 發(fā)送出去。

HTTP 請(qǐng)求響應(yīng)實(shí)例

用戶在登陸頁面輸入用戶名和密碼,點(diǎn)擊登陸后,瀏覽器發(fā)出了這樣的 HTTP 請(qǐng)求:

HTTP 請(qǐng)求數(shù)據(jù)由三部分組成,分別是請(qǐng)求行、請(qǐng)求報(bào)頭、請(qǐng)求正文。當(dāng)這個(gè) HTTP 請(qǐng)求數(shù)據(jù)到達(dá) Tomcat 后,Tomcat 會(huì)把 HTTP 請(qǐng)求數(shù)據(jù)字節(jié)流解析成一個(gè) Request 對(duì)象,這個(gè) Request 對(duì)象封裝了 HTTP 所有的請(qǐng)求信息。接著 Tomcat 把這個(gè) Request 對(duì)象交給 Web 應(yīng)用去處理,處理完后得到一個(gè) Response 對(duì)象,Tomcat 會(huì)把這個(gè) Response 對(duì)象轉(zhuǎn)成 HTTP 格式的響應(yīng)數(shù)據(jù)并發(fā)送給瀏覽器。

HTTP 的響應(yīng)也是由三部分組成,分別是狀態(tài)行、響應(yīng)報(bào)頭、報(bào)文主體。同樣,我還以極客時(shí)間登陸請(qǐng)求的響應(yīng)為例。

Cookie 和 Session

我們知道,HTTP 協(xié)議有個(gè)特點(diǎn)是無狀態(tài),請(qǐng)求與請(qǐng)求之間是沒有關(guān)系的。這樣會(huì)出現(xiàn)一個(gè)很尷尬的問題:Web 應(yīng)用不知道你是誰。因此 HTTP 協(xié)議需要一種技術(shù)讓請(qǐng)求與請(qǐng)求之間建立起聯(lián)系,并且服務(wù)器需要知道這個(gè)請(qǐng)求來自哪個(gè)用戶,于是 Cookie 技術(shù)出現(xiàn)了。

Cookie 是 HTTP 報(bào)文的一個(gè)請(qǐng)求頭,Web 應(yīng)用可以將用戶的標(biāo)識(shí)信息或者其他一些信息(用戶名等)存儲(chǔ)在 Cookie 中。用戶經(jīng)過驗(yàn)證之后,每次 HTTP 請(qǐng)求報(bào)文中都包含 Cookie,這樣服務(wù)器讀取這個(gè) Cookie 請(qǐng)求頭就知道用戶是誰了。Cookie 本質(zhì)上就是一份存儲(chǔ)在用戶本地的文件,里面包含了每次請(qǐng)求中都需要傳遞的信息。

由于 Cookie 以明文的方式存儲(chǔ)在本地,而 Cookie 中往往帶有用戶信息,這樣就造成了非常大的安全隱患。而 Session 的出現(xiàn)解決了這個(gè)問題,Session 可以理解為服務(wù)器端開辟的存儲(chǔ)空間,里面保存了用戶的狀態(tài),用戶信息以 Session 的形式存儲(chǔ)在服務(wù)端。當(dāng)用戶請(qǐng)求到來時(shí),服務(wù)端可以把用戶的請(qǐng)求和用戶的 Session 對(duì)應(yīng)起來。那么 Session 是怎么和請(qǐng)求對(duì)應(yīng)起來的呢?答案是通過 Cookie,瀏覽器在 Cookie 中填充了一個(gè) Session ID 之類的字段用來標(biāo)識(shí)請(qǐng)求。

具體工作過程是這樣的:服務(wù)器在創(chuàng)建 Session 的同時(shí),會(huì)為該 Session 生成唯一的 Session ID,當(dāng)瀏覽器再次發(fā)送請(qǐng)求的時(shí)候,會(huì)將這個(gè) Session ID 帶上,服務(wù)器接受到請(qǐng)求之后就會(huì)依據(jù) Session ID 找到相應(yīng)的 Session,找到 Session 后,就可以在 Session 中獲取或者添加內(nèi)容了。而這些內(nèi)容只會(huì)保存在服務(wù)器中,發(fā)到客戶端的只有 Session ID,這樣相對(duì)安全,也節(jié)省了網(wǎng)絡(luò)流量,因?yàn)椴恍枰?Cookie 中存儲(chǔ)大量用戶信息。

那么 Session 在何時(shí)何地創(chuàng)建呢?當(dāng)然還是在服務(wù)器端程序運(yùn)行的過程中創(chuàng)建的,不同語言實(shí)現(xiàn)的應(yīng)用程序有不同的創(chuàng)建 Session 的方法。在 Java 中,是 Web 應(yīng)用程序在調(diào)用 HttpServletRequest 的 getSession 方法時(shí),由 Web 容器(比如 Tomcat)創(chuàng)建的。

Tomcat 的 Session 管理器提供了多種持久化方案來存儲(chǔ) Session,通常會(huì)采用高性能的存儲(chǔ)方式,比如 Redis,并且通過集群部署的方式,防止單點(diǎn)故障,從而提升高可用。同時(shí),Session 有過期時(shí)間,因此 Tomcat 會(huì)開啟后臺(tái)線程定期的輪詢,如果 Session 過期了就將 Session 失效。

Servlet規(guī)范

HTTP 服務(wù)器怎么知道要調(diào)用哪個(gè) Java 類的哪個(gè)方法呢。最直接的做法是在 HTTP 服務(wù)器代碼里寫一大堆 if else 邏輯判斷:如果是 A 請(qǐng)求就調(diào) X 類的 M1 方法,如果是 B 請(qǐng)求就調(diào) Y 類的 M2 方法。但這樣做明顯有問題,因?yàn)?HTTP 服務(wù)器的代碼跟業(yè)務(wù)邏輯耦合在一起了,如果新加一個(gè)業(yè)務(wù)方法還要改 HTTP 服務(wù)器的代碼。

那該怎么解決這個(gè)問題呢?我們知道,面向接口編程是解決耦合問題的法寶,于是有一伙人就定義了一個(gè)接口,各種業(yè)務(wù)類都必須實(shí)現(xiàn)這個(gè)接口,這個(gè)接口就叫 Servlet 接口,有時(shí)我們也把實(shí)現(xiàn)了 Servlet 接口的業(yè)務(wù)類叫作 Servlet。

但是這里還有一個(gè)問題,對(duì)于特定的請(qǐng)求,HTTP 服務(wù)器如何知道由哪個(gè) Servlet 來處理呢?Servlet 又是由誰來實(shí)例化呢?顯然 HTTP 服務(wù)器不適合做這個(gè)工作,否則又和業(yè)務(wù)類耦合了。

于是,還是那伙人又發(fā)明了 Servlet 容器,Servlet 容器用來加載和管理業(yè)務(wù)類。HTTP 服務(wù)器不直接跟業(yè)務(wù)類打交道,而是把請(qǐng)求交給 Servlet 容器去處理,Servlet 容器會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到具體的 Servlet,如果這個(gè) Servlet 還沒創(chuàng)建,就加載并實(shí)例化這個(gè) Servlet,然后調(diào)用這個(gè) Servlet 的接口方法。因此 Servlet 接口其實(shí)是 Servlet 容器跟具體業(yè)務(wù)類之間的接口。下面我們通過一張圖來加深理解。

Servlet 接口和 Servlet 容器這一整套規(guī)范叫作 Servlet 規(guī)范。Tomcat 和 Jetty 都按照 Servlet 規(guī)范的要求實(shí)現(xiàn)了 Servlet 容器,同時(shí)它們也具有 HTTP 服務(wù)器的功能。作為 Java 程序員,如果我們要實(shí)現(xiàn)新的業(yè)務(wù)功能,只需要實(shí)現(xiàn)一個(gè) Servlet,并把它注冊(cè)到 Tomcat(Servlet 容器)中,剩下的事情就由 Tomcat 幫我們處理了。

Servlet 接口定義了下面五個(gè)方法:

public interface Servlet {
    void init(ServletConfig config) throws ServletException;
    
    ServletConfig getServletConfig();
    
    void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;
    
    String getServletInfo();
    
    void destroy();
}

其中最重要是的 service 方法,具體業(yè)務(wù)類在這個(gè)方法里實(shí)現(xiàn)處理邏輯。這個(gè)方法有兩個(gè)參數(shù):ServletRequest 和 ServletResponse。ServletRequest 用來封裝請(qǐng)求信息,ServletResponse 用來封裝響應(yīng)信息,因此本質(zhì)上這兩個(gè)類是對(duì)通信協(xié)議的封裝。

HTTP 協(xié)議中的請(qǐng)求和響應(yīng)就是對(duì)應(yīng)了 HttpServletRequest 和 HttpServletResponse 這兩個(gè)類。你可以通過 HttpServletRequest 來獲取所有請(qǐng)求相關(guān)的信息,包括請(qǐng)求路徑、Cookie、HTTP 頭、請(qǐng)求參數(shù)等。此外, 我們還可以通過 HttpServletRequest 來創(chuàng)建和獲取 Session。而 HttpServletResponse 是用來封裝 HTTP 響應(yīng)的。

你可以看到接口中還有兩個(gè)跟生命周期有關(guān)的方法 init 和 destroy,這是一個(gè)比較貼心的設(shè)計(jì),Servlet 容器在加載 Servlet 類的時(shí)候會(huì)調(diào)用 init 方法,在卸載的時(shí)候會(huì)調(diào)用 destroy 方法。我們可能會(huì)在 init 方法里初始化一些資源,并在 destroy 方法里釋放這些資源,比如 Spring MVC 中的 DispatcherServlet,就是在 init 方法里創(chuàng)建了自己的 Spring 容器。

你還會(huì)注意到 ServletConfig 這個(gè)類,ServletConfig 的作用就是封裝 Servlet 的初始化參數(shù)。你可以在web.xml給 Servlet 配置參數(shù),并在程序里通過 getServletConfig 方法拿到這些參數(shù)。

我們知道,有接口一般就有抽象類,抽象類用來實(shí)現(xiàn)接口和封裝通用的邏輯,因此 Servlet 規(guī)范提供了 GenericServlet 抽象類,我們可以通過擴(kuò)展它來實(shí)現(xiàn) Servlet。雖然 Servlet 規(guī)范并不在乎通信協(xié)議是什么,但是大多數(shù)的 Servlet 都是在 HTTP 環(huán)境中處理的,因此 Servet 規(guī)范還提供了 HttpServlet 來繼承 GenericServlet,并且加入了 HTTP 特性。這樣我們通過繼承 HttpServlet 類來實(shí)現(xiàn)自己的 Servlet,只需要重寫兩個(gè)方法:doGet 和 doPost。

Servlet 容器

當(dāng)客戶請(qǐng)求某個(gè)資源時(shí),HTTP 服務(wù)器會(huì)用一個(gè) ServletRequest 對(duì)象把客戶的請(qǐng)求信息封裝起來,然后調(diào)用 Servlet 容器的 service 方法,Servlet 容器拿到請(qǐng)求后,根據(jù)請(qǐng)求的 URL 和 Servlet 的映射關(guān)系,找到相應(yīng)的 Servlet,如果 Servlet 還沒有被加載,就用反射機(jī)制創(chuàng)建這個(gè) Servlet,并調(diào)用 Servlet 的 init 方法來完成初始化,接著調(diào)用 Servlet 的 service 方法來處理請(qǐng)求,把 ServletResponse 對(duì)象返回給 HTTP 服務(wù)器,HTTP 服務(wù)器會(huì)把響應(yīng)發(fā)送給客戶端

Web 應(yīng)用

Servlet 容器會(huì)實(shí)例化和調(diào)用 Servlet,那 Servlet 是怎么注冊(cè)到 Servlet 容器中的呢?一般來說,我們是以 Web 應(yīng)用程序的方式來部署 Servlet 的,而根據(jù) Servlet 規(guī)范,Web 應(yīng)用程序有一定的目錄結(jié)構(gòu),在這個(gè)目錄下分別放置了 Servlet 的類文件、配置文件以及靜態(tài)資源,Servlet 容器通過讀取配置文件,就能找到并加載 Servlet。Web 應(yīng)用的目錄結(jié)構(gòu)大概是下面這樣的:

| -  MyWebApp
      | -  WEB-INF/web.xml        -- 配置文件,用來配置Servlet等
      | -  WEB-INF/lib/           -- 存放Web應(yīng)用所需各種JAR包
      | -  WEB-INF/classes/       -- 存放你的應(yīng)用類,比如Servlet類
      | -  META-INF/              -- 目錄存放工程的一些信息

Servlet 規(guī)范里定義了 ServletContext 這個(gè)接口來對(duì)應(yīng)一個(gè) Web 應(yīng)用。Web 應(yīng)用部署好后,Servlet 容器在啟動(dòng)時(shí)會(huì)加載 Web 應(yīng)用,并為每個(gè) Web 應(yīng)用創(chuàng)建唯一的 ServletContext 對(duì)象。你可以把 ServletContext 看成是一個(gè)全局對(duì)象,一個(gè) Web 應(yīng)用可能有多個(gè) Servlet,這些 Servlet 可以通過全局的 ServletContext 來共享數(shù)據(jù),這些數(shù)據(jù)包括 Web 應(yīng)用的初始化參數(shù)、Web 應(yīng)用目錄下的文件資源等。由于 ServletContext 持有所有 Servlet 實(shí)例,你還可以通過它來實(shí)現(xiàn) Servlet 請(qǐng)求的轉(zhuǎn)發(fā)。

擴(kuò)展機(jī)制

引入了 Servlet 規(guī)范后,你不需要關(guān)心 Socket 網(wǎng)絡(luò)通信、不需要關(guān)心 HTTP 協(xié)議,也不需要關(guān)心你的業(yè)務(wù)類是如何被實(shí)例化和調(diào)用的,因?yàn)檫@些都被 Servlet 規(guī)范標(biāo)準(zhǔn)化了,你只要關(guān)心怎么實(shí)現(xiàn)的你的業(yè)務(wù)邏輯。這對(duì)于程序員來說是件好事,但也有不方便的一面。所謂規(guī)范就是說大家都要遵守,就會(huì)千篇一律,但是如果這個(gè)規(guī)范不能滿足你的業(yè)務(wù)的個(gè)性化需求,就有問題了,因此設(shè)計(jì)一個(gè)規(guī)范或者一個(gè)中間件,要充分考慮到可擴(kuò)展性。Servlet 規(guī)范提供了兩種擴(kuò)展機(jī)制:Filter 和 Listener。

Filter 是過濾器,這個(gè)接口允許你對(duì)請(qǐng)求和響應(yīng)做一些統(tǒng)一的定制化處理,比如你可以根據(jù)請(qǐng)求的頻率來限制訪問,或者根據(jù)國家地區(qū)的不同來修改響應(yīng)內(nèi)容。過濾器的工作原理是這樣的:Web 應(yīng)用部署完成后,Servlet 容器需要實(shí)例化 Filter 并把 Filter 鏈接成一個(gè) FilterChain。當(dāng)請(qǐng)求進(jìn)來時(shí),獲取第一個(gè) Filter 并調(diào)用 doFilter 方法,doFilter 方法負(fù)責(zé)調(diào)用這個(gè) FilterChain 中的下一個(gè) Filter。

Listener 是監(jiān)聽器,這是另一種擴(kuò)展機(jī)制。當(dāng) Web 應(yīng)用在 Servlet 容器中運(yùn)行時(shí),Servlet 容器內(nèi)部會(huì)不斷的發(fā)生各種事件,如 Web 應(yīng)用的啟動(dòng)和停止、用戶請(qǐng)求到達(dá)等。 Servlet 容器提供了一些默認(rèn)的監(jiān)聽器來監(jiān)聽這些事件,當(dāng)事件發(fā)生時(shí),Servlet 容器會(huì)負(fù)責(zé)調(diào)用監(jiān)聽器的方法。當(dāng)然,你可以定義自己的監(jiān)聽器去監(jiān)聽你感興趣的事件,將監(jiān)聽器配置在web.xml中。比如 Spring 就實(shí)現(xiàn)了自己的監(jiān)聽器,來監(jiān)聽 ServletContext 的啟動(dòng)事件,目的是當(dāng) Servlet 容器啟動(dòng)時(shí),創(chuàng)建并初始化全局的 Spring 容器。

Tomcat下載地址:https://tomcat.apache.org/download-80.cgi

/bin:存放 Windows 或 Linux 平臺(tái)上啟動(dòng)和關(guān)閉 Tomcat 的腳本文件。
/conf:存放 Tomcat 的各種全局配置文件,其中最重要的是server.xml。
/lib:存放 Tomcat 以及所有 Web 應(yīng)用都可以訪問的 JAR 文件。
/logs:存放 Tomcat 執(zhí)行時(shí)產(chǎn)生的日志文件。
/work:存放 JSP 編譯后產(chǎn)生的 Class 文件。
/webapps:Tomcat 的 Web 應(yīng)用目錄,默認(rèn)情況下把 Web 應(yīng)用放在這個(gè)目錄下。

打開 Tomcat 的日志目錄,也就是 Tomcat 安裝目錄下的 logs 目錄。Tomcat 的日志信息分為兩類 :一是運(yùn)行日志,它主要記錄運(yùn)行過程中的一些信息,尤其是一些異常錯(cuò)誤日志信息 ;二是訪問日志,它記錄訪問的時(shí)間、IP 地址、訪問的路徑等相關(guān)信息。

  • catalina.***.log 主要是記錄 Tomcat 啟動(dòng)過程的信息,在這個(gè)文件可以看到啟動(dòng)的 JVM 參數(shù)以及操作系統(tǒng)等日志信息。
  • catalina.out是 Tomcat 的標(biāo)準(zhǔn)輸出(stdout)和標(biāo)準(zhǔn)錯(cuò)誤(stderr),這是在 Tomcat 的啟動(dòng)腳本里指定的,如果沒有修改的話 stdout 和 stderr 會(huì)重定向到這里。所以在這個(gè)文件里可以看到我們?cè)贛yServlet.java程序里打印出來的信息
  • localhost.**.log主要記錄 Web 應(yīng)用在初始化過程中遇到的未處理的異常,會(huì)被 Tomcat 捕獲而輸出這個(gè)日志文件。
  • localhost_access_log.**.txt存放訪問 Tomcat 的請(qǐng)求日志,包括 IP 地址以及請(qǐng)求的路徑、時(shí)間、請(qǐng)求協(xié)議以及狀態(tài)碼等信息。
  • manager.***.log/host-manager.***.log存放 Tomcat 自帶的 Manager 項(xiàng)目的日志信息。

概要:

  1. Tomcat各核心組件認(rèn)知
  2. server.xml 配置詳解

一、Tomcat各組件認(rèn)知

知識(shí)點(diǎn):

  1. Tomcat架構(gòu)說明
  2. Tomcat組件及關(guān)系詳情介紹
  3. Tomcat啟動(dòng)參數(shù)說明
  4. Tomcat架構(gòu)說明

Tomcat是一個(gè)基于JAVA的WEB容器,其實(shí)現(xiàn)了JAVA EE中的 Servlet 與 jsp 規(guī)范,與Nginx apache 服務(wù)器不同在于一般用于動(dòng)態(tài)請(qǐng)求處理。在架構(gòu)設(shè)計(jì)上采用面向組件的方式設(shè)計(jì)。即整體功能是通過組件的方式拼裝完成。另外每個(gè)組件都可以被替換以保證靈活性。

2.Tomcat 各組件及關(guān)系

Server 和 Service
Connector 連接器
HTTP 1.1
SSL https
AJP( Apache JServ Protocol) apache 私有協(xié)議,用于apache 反向代理Tomcat
Container 
Engine 引擎 catalina
Host 虛擬機(jī) 基于域名 分發(fā)請(qǐng)求
Context 隔離各個(gè)WEB應(yīng)用 每個(gè)Context的 ClassLoader都是獨(dú)立
Component 
Manager (管理器)
logger (日志管理)
loader (載入器)
pipeline (管道)
valve (管道中的閥)

二、Tomcat server.xml 配置詳解


server

root元素:server 的頂級(jí)配置 主要屬性: port:執(zhí)行關(guān)閉命令的端口號(hào) shutdown:關(guān)閉命令

演示shutdown的用法 #基于telent 執(zhí)行SHUTDOWN 命令即可關(guān)閉(必須大寫) telnet 127.0.0.1 8005 SHUTDOWN

service

服務(wù):將多個(gè)connector 與一個(gè)Engine組合成一個(gè)服務(wù),可以配置多個(gè)服務(wù)。

Connector

連接器:用于接收 指定協(xié)議下的連接 并指定給唯一的Engine 進(jìn)行處理。 主要屬性:

  • protocol 監(jiān)聽的協(xié)議,默認(rèn)是http/1.1
  • port 指定服務(wù)器端要?jiǎng)?chuàng)建的端口號(hào)
  • minSpareThreads服務(wù)器啟動(dòng)時(shí)創(chuàng)建的處理請(qǐng)求的線程數(shù)
  • maxThreads 最大可以創(chuàng)建的處理請(qǐng)求的線程數(shù)
  • enableLookups 如果為true,則可以通過調(diào)用request.getRemoteHost()進(jìn)行DNS查詢來得到遠(yuǎn)程客戶端的實(shí)際主機(jī)名,若為false則不進(jìn)行DNS查詢,而是返回其ip地址
  • redirectPort 指定服務(wù)器正在處理http請(qǐng)求時(shí)收到了一個(gè)SSL傳輸請(qǐng)求后重定向的端口號(hào)
  • acceptCount 指定當(dāng)所有可以使用的處理請(qǐng)求的線程數(shù)都被使用時(shí),可以放到處理隊(duì)列中的請(qǐng)求數(shù),超過這個(gè)數(shù)的請(qǐng)求將不予處理
  • connectionTimeout 指定超時(shí)的時(shí)間數(shù)(以毫秒為單位)
  • SSLEnabled 是否開啟 sll 驗(yàn)證,在Https 訪問時(shí)需要開啟。生成證書: keytool -genkey -v -alias testKey -keyalg RSA -validity 3650 -keystore D:\test.keystore
  • [ ] 演示配置多個(gè)Connector
<Connector port="8860" protocol="org.apache.coyote.http11.Http11NioProtocol"
                connectionTimeout="20000"
                redirectPort="8862"
                URIEncoding="UTF-8"
                useBodyEncodingForURI="true"
                compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css,application/x-json,application/json,application/x-javascript"
                maxThreads="1024" minSpareThreads="200"
                acceptCount="800"
                maxConnections="10000"
                enableLookups="false"
        />

Engine

引擎:用于處理連接的執(zhí)行器,默認(rèn)的引擎是catalina。一個(gè)service 中只能配置一個(gè)Engine。 主要屬性:name 引擎名稱 defaultHost 默認(rèn)host

Host

虛擬機(jī):基于域名匹配至指定虛擬機(jī)。類似于nginx 當(dāng)中的server,默認(rèn)的虛擬機(jī)是localhost. 主要屬性:

演示配置多個(gè)Host

<Host name="www.wukong.com"  appBase="/usr/www/wukong"  unpackWARs="true" autoDeploy="true"> 
	<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="www.wukong.com.access_log" 
			suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" /> 
</Host>

Context

應(yīng)用上下文:一個(gè)host 下可以配置多個(gè)Context ,每個(gè)Context 都有其獨(dú)立的classPath。相互隔離,以免造成ClassPath 沖突。 主要屬性:

演示配置多個(gè)Context

<Context path="/testweb" docBase="testweb.war"  reloadbale="true"/>

Valve 閥門:可以理解成

的過濾器,具體配置要基于具體的Valve 接口的子類。以下即為一個(gè)訪問日志的Valve

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="www.wukong.com.access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

三、Tomcat 部署腳本編寫

Tomcat啟動(dòng)參數(shù)說明

我們平時(shí)啟動(dòng)Tomcat過程是怎么樣的?

  1. 復(fù)制WAR包至Tomcat webapp 目錄。
  2. 執(zhí)行starut.bat 腳本啟動(dòng)。
  3. 啟動(dòng)過程中war 包會(huì)被自動(dòng)解壓裝載。

但是我們?cè)贓clipse 或idea 中啟動(dòng)WEB項(xiàng)目的時(shí)候 也是把War包復(fù)雜至webapps 目錄解壓嗎?顯然不是,其真正做法是在Tomcat程序文件之外創(chuàng)建了一個(gè)部署目錄,在一般生產(chǎn)環(huán)境中也是這么做的 即:Tomcat 程序目錄和部署目錄分開 。 我們只需要在啟動(dòng)時(shí)指定CATALINA_HOME 與 CATALINA_BASE 參數(shù)即可實(shí)現(xiàn)。

| 啟動(dòng)參數(shù) | 描述說明 | |:----|:----| | JAVA_OPTS | jvm 啟動(dòng)參數(shù) , 設(shè)置內(nèi)存 編碼等 -Xms100m -Xmx200m -Dfile.encoding=UTF-8 | | JAVA_HOME | 指定jdk 目錄,如果未設(shè)置從java 環(huán)境變量當(dāng)中去找。 | | CATALINA_HOME | Tomcat 程序根目錄 | | CATALINA_BASE | 應(yīng)用部署目錄,默認(rèn)為$CATALINA_HOME | | CATALINA_OUT | 應(yīng)用日志輸出目錄:默認(rèn)$CATALINA_BASE/log | | CATALINA_TMPDIR | 應(yīng)用臨時(shí)目錄:默認(rèn):$CATALINA_BASE/temp |

可以編寫一個(gè)腳本 來實(shí)現(xiàn)自定義配置:

ln -s /home/wukong/apache-tomcat-8.5.56 apache-tomcat

更新 啟動(dòng) 腳本

#!/bin/bash 
export JAVA_OPTS="-Xms100m -Xmx200m"
export CATALINA_HOME=/home/wukong/apache-tomcat
export CATALINA_BASE="`pwd`"
 
case $1 in
        start)
        $CATALINA_HOME/bin/catalina.sh start
                echo start success!!
        ;;
        stop)
                $CATALINA_HOME/bin/catalina.sh stop
                echo stop success!!
        ;;
        restart)
        $CATALINA_HOME/bin/catalina.sh stop
                echo stop success!!
                sleep 3
        $CATALINA_HOME/bin/catalina.sh start
        echo start success!!
        ;;
        version)
        $CATALINA_HOME/bin/catalina.sh version
        ;;
        configtest)
        $CATALINA_HOME/bin/catalina.sh configtest
        ;;
        esac
exit 0

docker 啟動(dòng)tomcat

docker run -id --name=test_tomcat -e JAVA_OPTS='-Xmx128m' -p 8888: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=true tomcat:8

源碼構(gòu)建

下載地址:https://tomcat.apache.org/download-80.cgi

配置

1.解壓源碼 apache-tomcat-8.5.57-src

2.apache-tomcat-8.5.57-src目錄下添加pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>Tomcat8.0</artifactId>
    <name>Tomcat8.0</name>
    <version>8.0</version>
 
    <build>
        <finalName>Tomcat8.0</finalName>
        <sourceDirectory>java</sourceDirectory>
        <testSourceDirectory>test</testSourceDirectory>
        <resources>
            <resource>
                <directory>java</directory>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <directory>test</directory>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.easymock</groupId>
            <artifactId>easymock</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>javax.xml</groupId>
            <artifactId>jaxrpc</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jdt.core.compiler</groupId>
            <artifactId>ecj</artifactId>
            <version>4.5.1</version>
        </dependency>
 
    </dependencies>
</project>

3.在apache-tomcat-8.5.57-src 同級(jí)目錄新建 catalina-home并保證目錄下面文件如下

注意: 上面文件夾apache-tomcat-8.5.57-src里面有的,就剪切過來,沒有的就新建一個(gè), bin conf webapps 應(yīng)該是從apache-tomcat-8.5.57-src剪切過來的

4.idea引入項(xiàng)目

File->Open 選擇解壓的C:\Users\wukong\Downloads\apache-tomcat-8.5.57-src\apache-tomcat-8.5.57-src

配置啟動(dòng)

MainClass: org.apache.catalina.startup.BootstrapVmOptions: -Dcatalina.home=C:\Users\wukong\Downloads\apache-tomcat-8.5.57-src\apache-tomcat-8.5.57-src\catalina-home

啟動(dòng)報(bào)錯(cuò)

TestCookieFilter 報(bào)錯(cuò)找不到這個(gè)類CookieFilter

解決方法:

1. 刪除:TestCookieFilter

啟動(dòng)后,訪問localhost:8080 報(bào)錯(cuò) org.apache.jasper.JasperException: java.lang.NullPointerException

解決方案:

org.apache.catalina.startup.Bootstrap 添加代碼塊

{
        JasperInitializer initializer =new JasperInitializer();
         }

以上就是Tomcat核心組件及應(yīng)用架構(gòu)詳解的詳細(xì)內(nèi)容,更多關(guān)于Tomcat核心組件及應(yīng)用架構(gòu)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

標(biāo)簽:朝陽 遵義 面試通知 雞西 荊門 運(yùn)城 隴南 連云港

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Tomcat核心組件及應(yīng)用架構(gòu)詳解》,本文關(guān)鍵詞  Tomcat,核心,組件,及,應(yīng)用,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Tomcat核心組件及應(yīng)用架構(gòu)詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于Tomcat核心組件及應(yīng)用架構(gòu)詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章