## Tomcat是什么?
* Tomcat 服務器Apache軟件基金會項目中的一個核心項目,是一個免費的開放源代碼的Web 應用服務器,屬于輕量級應用服務器,在中小型系統和并發訪問用戶不是很多的場合下被普遍使用,是開發和調試JSP 程序的首選。
## Tomcat的缺省端口是多少,怎么修改
* 默認8080
* 修改端口號方式
1. 找到Tomcat目錄下的conf文件夾
2. 進入conf文件夾里面找到server.xml文件
3. 打開server.xml文件
4. 在server.xml文件里面找到下列信息
5. 把Connector標簽的8080端口改成你想要的端口
## 怎么在Linux上安裝Tomcat
1. 先去下載Tomcat的安裝包,gz結尾的(代表Linux上的Tomcat)
2. 上傳到Linux上,解壓
3. 修改端口號,也可以不修改把。如果要修改在server.xml內改
4. 修改好了之后,你就進入你這個tomcat下的bin目錄,輸入:./startup.sh 這樣就啟動成功了。
## 怎么在Linux部署項目
* 先使用eclipse或IDEA把項目打成.war包,然后上傳到Linux服務器,然后把項目放在Tomcat的bin目錄下的webapps,在重啟Tomcat就行了。
## Tomcat的目錄結構
* /bin:存放用于啟動和暫停Tomcat的腳本
* /conf:存放Tomcat的配置文件
* /lib:存放Tomcat服務器需要的各種jar包
* /logs:存放Tomcat的日志文件
* /temp:Tomcat運行時用于存放臨時文件
* /webapps:web應用的發布目錄
* /work:Tomcat把有jsp生成Servlet防御此目錄下
## 類似Tomcat,發布jsp運行的web服務器還有那些:
* 1、Resin Resin提供了最快的jsp/servlets運行平臺。在java和javascript的支持下,Resin可以為任務靈活選用合適的開發語言。Resin的一種先進的語言XSL(XML stylesheet language)可以使得形式和內容相分離。
* 2、Jetty Jetty是一個開源的servlet容器,它為基于Java的web內容,例如JSP和servlet提供運行環境。Jetty是使用Java語言編寫的,它的API以一組JAR包的形式發布。開發人員可以將Jetty容器實例化成一個對象,可以迅速為一些獨立運行(stand-alone)的Java應用提供網絡和web連接。
* 3、WebLogic BEA WebLogic是用于開發、集成、部署和管理大型分布式Web應用、網絡應用和數據庫應用的Java應用服務器。將Java的動態功能和Java Enterprise標準的安全性引入大型網絡應用的開發、集成、部署和管理之中。
* 4、jboss Jboss是一個基于J2EE的開放源代碼的應用服務器。 JBoss代碼遵循LGPL許可,可以在任何商業應用中免費使用,而不用支付費用。JBoss是一個管理EJB的容器和服務器,支持EJB 1.1、EJB 2.0和EJB3的規范。但JBoss核心服務不包括支持servlet/JSP的WEB容器,一般與Tomcat或Jetty綁定使用。
## tomcat 如何優化?
1. 改Tomcat最大線程連接數 需要修改conf/server.xml文件,修改里面的配置文件: maxThreads=”150”//Tomcat使用線程來處理接收的每個請求。這個值表示Tomcat可 創建的最大的線程數。默認值200。可以根據機器的時期性能和內存大小調整,一般 可以在400-500。最大可以在800左右。
2. Tomcat內存優化,啟動時告訴JVM我要多大內存 調優方式的話,修改: Windows 下的catalina.bat Linux 下的catalina.sh 修改方式如: JAVA\_OPTS=’-Xms256m -Xmx512m’-Xms JVM初始化堆的大小-Xmx JVM堆的最大值 實際參數大
## tomcat 有哪幾種Connector 運行模式(優化)?
**下面,我們先大致了解Tomcat Connector的三種運行模式。**
1. **BIO:同步并阻塞** 一個線程處理一個請求。缺點:并發量高時,線程數較多,浪費資源。Tomcat7或以下,在Linux系統中默認使用這種方式。 **配制項**:protocol=”HTTP/1.1”
2. **NIO:同步非阻塞IO** 利用Java的異步IO處理,可以通過少量的線程處理大量的請求,可以復用同一個線程處理多個connection(多路復用)。
Tomcat8在Linux系統中默認使用這種方式。 Tomcat7必須修改Connector配置來啟動。 **配制項**:protocol=”org.apache.coyote.http11.Http11NioProtocol” **備注**:我們常用的Jetty,Mina,ZooKeeper等都是基于java nio實現.
3. APR:即Apache Portable Runtime,從操作系統層面解決io阻塞問題。 **AIO方式**,**異步非阻塞IO**(Java NIO2又叫AIO) 主要與NIO的區別主要是操作系統的底層區別.可以做個比喻:比作快遞,NIO就是網購后要自己到官網查下快遞是否已經到了(可能是多次),然后自己去取快遞;AIO就是快遞員送貨上門了(不用關注快遞進度)。
**配制項**:protocol=”org.apache.coyote.http11.Http11AprProtocol” **備注**:需在本地服務器安裝APR庫。Tomcat7或Tomcat8在Win7或以上的系統中啟動默認使用這種方式。Linux如果安裝了apr和native,Tomcat直接啟動就支持apr。
## Tomcat有幾種部署方式?
**在Tomcat中部署Web應用的方式主要有如下幾種:**
1. 利用Tomcat的自動部署。
把web應用拷貝到webapps目錄。Tomcat在啟動時會加載目錄下的應用,并將編譯后的結果放入work目錄下。
2. 使用Manager App控制臺部署。
在tomcat主頁點擊“Manager App” 進入應用管理控制臺,可以指定一個web應用的路徑或war文件。
3. 修改conf/server.xml文件部署。
修改conf/server.xml文件,增加Context節點可以部署應用。
4. 增加自定義的Web部署文件。
在conf/Catalina/localhost/ 路徑下增加 xyz.xml文件,內容是Context節點,可以部署應用。
## tomcat容器是如何創建servlet類實例?用到了什么原理?
1. 當容器啟動時,會讀取在webapps目錄下所有的web應用中的web.xml文件,然后對 **xml文件進行解析,并讀取servlet注冊信息**。然后,將每個應用中注冊的servlet類都進行加載,并通過 **反射的方式實例化**。(有時候也是在第一次請求時實例化)
2. 在servlet注冊時加上1如果為正數,則在一開始就實例化,如果不寫或為負數,則第一次請求實例化。
## Tomcat工作模式
* Tomcat作為servlet容器,有三種工作模式:
* 1、獨立的servlet容器,servlet容器是web服務器的一部分;
* 2、進程內的servlet容器,servlet容器是作為web服務器的插件和java容器的實現,web服務器插件在內部地址空間打開一個jvm使得java容器在內部得以運行。反應速度快但伸縮性不足;
* 3、進程外的servlet容器,servlet容器運行于web服務器之外的地址空間,并作為web服務器的插件和java容器實現的結合。反應時間不如進程內但伸縮性和穩定性比進程內優;
* 進入Tomcat的請求可以根據Tomcat的工作模式分為如下兩類:
* Tomcat作為應用程序服務器:請求來自于前端的web服務器,這可能是Apache, IIS, Nginx等;
* Tomcat作為獨立服務器:請求來自于web瀏覽器;
* 面試時問到Tomcat相關問題的幾率并不高,正式因為如此,很多人忽略了對Tomcat相關技能的掌握,下面這一篇文章整理了Tomcat相關的系統架構,介紹了Server、Service、Connector、Container之間的關系,各個模塊的功能,可以說把這幾個掌握住了,Tomcat相關的面試題你就不會有任何問題了!另外,在面試的時候你還要有意識無意識的往Tomcat這個地方引,就比如說常見的Spring MVC的執行流程,一個URL的完整調用鏈路,這些相關的題目你是可以往Tomcat處理請求的這個過程去說的!掌握了Tomcat這些技能,面試官一定會佩服你的!
* 學了本章之后你應該明白的是:
* Server、Service、Connector、Container四大組件之間的關系和聯系,以及他們的主要功能點;
* Tomcat執行的整體架構,請求是如何被一步步處理的;
* Engine、Host、Context、Wrapper相關的概念關系;
* Container是如何處理請求的;
* Tomcat用到的相關設計模式;
## Tomcat頂層架構
* 俗話說,站在巨人的肩膀上看世界,一般學習的時候也是先總覽一下整體,然后逐個部分個個擊破,最后形成思路,了解具體細節,Tomcat的結構很復雜,但是 Tomcat 非常的模塊化,找到了 Tomcat 最核心的模塊,問題才可以游刃而解,了解了 Tomcat 的整體架構對以后深入了解 Tomcat 來說至關重要!
* 先上一張Tomcat的頂層結構圖(圖A),如下:

* Tomcat中最頂層的容器是Server,代表著整個服務器,從上圖中可以看出,一個Server可以包含至少一個Service,即可以包含多個Service,用于具體提供服務。
* Service主要包含兩個部分:Connector和Container。從上圖中可以看出 Tomcat 的心臟就是這兩個組件,他們的作用如下:
* Connector用于處理連接相關的事情,并提供Socket與Request請求和Response響應相關的轉化;
* Container用于封裝和管理Servlet,以及具體處理Request請求;
* 一個Tomcat中只有一個Server,一個Server可以包含多個Service,一個Service只有一個Container,但是可以有多個Connectors,這是因為一個服務可以有多個連接,如同時提供Http和Https鏈接,也可以提供向相同協議不同端口的連接,示意圖如下(Engine、Host、Context下面會說到):

* 多個 Connector 和一個 Container 就形成了一個 Service,有了 Service 就可以對外提供服務了,但是 Service 還要一個生存的環境,必須要有人能夠給她生命、掌握其生死大權,那就非 Server 莫屬了!所以整個 Tomcat 的生命周期由 Server 控制。
* 另外,上述的包含關系或者說是父子關系,都可以在tomcat的conf目錄下的server.xml配置文件中看出,下圖是刪除了注釋內容之后的一個完整的server.xml配置文件(Tomcat版本為8.0)

* 詳細的配置文件內容可以到Tomcat官網查看:[Tomcat配置文件](https://link.juejin.cn?target=http%3A%2F%2Ftomcat.apache.org%2Ftomcat-8.0-doc%2Findex.html "http://tomcat.apache.org/tomcat-8.0-doc/index.html")
* 上邊的配置文件,還可以通過下邊的一張結構圖更清楚的理解:

* Server標簽設置的端口號為8005,shutdown=”SHUTDOWN” ,表示在8005端口監聽“SHUTDOWN”命令,如果接收到了就會關閉Tomcat。一個Server有一個Service,當然還可以進行配置,一個Service有多個Connector,Service左邊的內容都屬于Container的,Service下邊是Connector。
### Tomcat頂層架構小結
1. Tomcat中只有一個Server,一個Server可以有多個Service,一個Service可以有多個Connector和一個Container;
2. Server掌管著整個Tomcat的生死大權;
3. Service 是對外提供服務的;
4. Connector用于接受請求并將請求封裝成Request和Response來具體處理;
5. Container用于封裝和管理Servlet,以及具體處理request請求;
* 知道了整個Tomcat頂層的分層架構和各個組件之間的關系以及作用,對于絕大多數的開發人員來說Server和Service對我們來說確實很遠,而我們開發中絕大部分進行配置的內容是屬于Connector和Container的,所以接下來介紹一下Connector和Container。
## Connector和Container的微妙關系
* 由上述內容我們大致可以知道一個請求發送到Tomcat之后,首先經過Service然后會交給我們的Connector,Connector用于接收請求并將接收的請求封裝為Request和Response來具體處理,Request和Response封裝完之后再交由Container進行處理,Container處理完請求之后再返回給Connector,最后在由Connector通過Socket將處理的結果返回給客戶端,這樣整個請求的就處理完了!
* Connector最底層使用的是Socket來進行連接的,Request和Response是按照HTTP協議來封裝的,所以Connector同時需要實現TCP/IP協議和HTTP協議!
* Tomcat既然需要處理請求,那么肯定需要先接收到這個請求,接收請求這個東西我們首先就需要看一下Connector!
* Connector架構分析
* Connector用于接受請求并將請求封裝成Request和Response,然后交給Container進行處理,Container處理完之后在交給Connector返回給客戶端。
* 因此,我們可以把Connector分為四個方面進行理解:
* Connector如何接受請求的?
* 如何將請求封裝成Request和Response的?
* 封裝完之后的Request和Response如何交給Container進行處理的?
* Container處理完之后如何交給Connector并返回給客戶端的?
* 首先看一下Connector的結構圖(圖B),如下所示:

* Connector就是使用ProtocolHandler來處理請求的,不同的ProtocolHandler代表不同的連接類型,比如:Http11Protocol使用的是普通Socket來連接的,Http11NioProtocol使用的是NioSocket來連接的。
* 其中ProtocolHandler由包含了三個部件:Endpoint、Processor、Adapter。
1. Endpoint用來處理底層Socket的網絡連接,Processor用于將Endpoint接收到的Socket封裝成Request,Adapter用于將Request交給Container進行具體的處理。
2. Endpoint由于是處理底層的Socket網絡連接,因此Endpoint是用來實現TCP/IP協議的,而Processor用來實現HTTP協議的,Adapter將請求適配到Servlet容器進行具體的處理。
3. Endpoint的抽象實現AbstractEndpoint里面定義的Acceptor和AsyncTimeout兩個內部類和一個Handler接口。Acceptor用于監聽請求,AsyncTimeout用于檢查異步Request的超時,Handler用于處理接收到的Socket,在內部調用Processor進行處理。
* 至此,我們應該很輕松的回答1,2,3的問題了,但是4還是不知道,那么我們就來看一下Container是如何進行處理的以及處理完之后是如何將處理完的結果返回給Connector的?
## Container架構分析
* Container用于封裝和管理Servlet,以及具體處理Request請求,在Container內部包含了4個子容器,結構圖如下(圖C):

* 4個子容器的作用分別是:
1. Engine:引擎,用來管理多個站點,一個Service最多只能有一個Engine;
2. Host:代表一個站點,也可以叫虛擬主機,通過配置Host就可以添加站點;
3. Context:代表一個應用程序,對應著平時開發的一套程序,或者一個WEB-INF目錄以及下面的web.xml文件;
4. Wrapper:每一Wrapper封裝著一個Servlet;
* 下面找一個Tomcat的文件目錄對照一下,如下圖所示:

* Context和Host的區別是Context表示一個應用,我們的Tomcat中默認的配置下webapps下的每一個文件夾目錄都是一個Context,其中ROOT目錄中存放著主應用,其他目錄存放著子應用,而整個webapps就是一個Host站點。
* 我們訪問應用Context的時候,如果是ROOT下的則直接使用域名就可以訪問,例如:www.baidu.com,如果是Host(webapps)下的其他應用,則可以使用www.baidu.com/docs進行訪問,當然默認指定的根應用(ROOT)是可以進行設定的,只不過Host站點下默認的主應用是ROOT目錄下的。
* 看到這里我們知道Container是什么,但是還是不知道Container是如何進行請求處理的以及處理完之后是如何將處理完的結果返回給Connector的?別急!下邊就開始探討一下Container是如何進行處理的!
### Container如何處理請求的
* Container處理請求是使用Pipeline-Valve管道來處理的!(Valve是閥門之意)
* Pipeline-Valve是**責任鏈模式**,責任鏈模式是指在一個請求處理的過程中有很多處理者依次對請求進行處理,每個處理者負責做自己相應的處理,處理完之后將處理后的結果返回,再讓下一個處理者繼續處理。

* 但是!Pipeline-Valve使用的責任鏈模式和普通的責任鏈模式有些不同!區別主要有以下兩點:
* 每個Pipeline都有特定的Valve,而且是在管道的最后一個執行,這個Valve叫做BaseValve,BaseValve是不可刪除的;
* 在上層容器的管道的BaseValve中會調用下層容器的管道。
* 我們知道Container包含四個子容器,而這四個子容器對應的BaseValve分別在:StandardEngineValve、StandardHostValve、StandardContextValve、StandardWrapperValve。
* Pipeline的處理流程圖如下(圖D):

* Connector在接收到請求后會首先調用最頂層容器的Pipeline來處理,這里的最頂層容器的Pipeline就是EnginePipeline(Engine的管道);
* 在Engine的管道中依次會執行EngineValve1、EngineValve2等等,最后會執行StandardEngineValve,在StandardEngineValve中會調用Host管道,然后再依次執行Host的HostValve1、HostValve2等,最后在執行StandardHostValve,然后再依次調用Context的管道和Wrapper的管道,最后執行到StandardWrapperValve。
* 當執行到StandardWrapperValve的時候,會在StandardWrapperValve中創建FilterChain,并調用其doFilter方法來處理請求,這個FilterChain包含著我們配置的與請求相匹配的Filter和Servlet,其doFilter方法會依次調用所有的Filter的doFilter方法和Servlet的service方法,這樣請求就得到了處理!
* 當所有的Pipeline-Valve都執行完之后,并且處理完了具體的請求,這個時候就可以將返回的結果交給Connector了,Connector在通過Socket的方式將結果返回給客戶端。
## 總結
* 至此,我們已經對Tomcat的整體架構有了大致的了解,從圖A、B、C、D可以看出來每一個組件的基本要素和作用。我們在腦海里應該有一個大概的輪廓了!如果你面試的時候,讓你簡單的聊一下Tomcat,上面的內容你能脫口而出嗎?當你能夠脫口而出的時候,面試官一定會對你刮目相看的!
- 常見面試題
- 一.Java常見面試題
- 1.Java基礎
- 3.面向對象概念
- 10.Java面試題
- Java基礎知識面試題(總結最全面的面試題)
- 設計模式面試題(總結最全面的面試題)
- Java集合面試題(總結最全面的面試題)
- JavaIO、BIO、NIO、AIO、Netty面試題(總結最全面的面試題)
- Java并發編程面試題(總結最全面的面試題)
- Java異常面試題(總結最全面的面試題)
- Java虛擬機(JVM)面試題(總結最全面的面試題)
- Spring面試題(總結最全面的面試題)
- Spring MVC面試題(總結最全面的面試題)
- Spring Boot面試題(總結最全面的面試題)
- Spring Cloud面試題(總結最全面的面試題)
- Redis面試題(總結最全面的面試題)
- MyBatis面試題(總結最全面的面試題)
- TCP、UDP、Socket、HTTP面試題(總結最全面的面試題)
- 二、MySQL面試題
- 1.基礎部分
- MySQL面試題(總結最全面的面試題)
- HBase相關面試題整理
- Nginx面試題(總結最全面的面試題)
- RabbitMQ面試題(總結最全面的面試題)
- Dubbo面試題(總結最全面的面試題)
- ZooKeeper面試題(總結最全面的面試題)
- Tomcat面試題(總結最全面的面試題)
- Linux面試題(總結最全面的面試題)
- 超詳細的Django面試題
- SSM面試題
- 15個高頻微信小程序面試題
- VUE面試題
- Python面試題
- 二、常見問題解答列表
- 1.查看端口及殺死進程
- 三、學習電子書