1.tomcat介紹
1.1概念
- Server:接受請求並解析,完成相關任務,返回處理結果
- Connector:開啓Socket並監聽客戶端請求,返回響應數據
- Container:負責具體的請求處理
- Engine:Container是一個通用的概念,而Engine是一個具體概念來負責具體的處理器請求
- Service:服務,接受請求、解析請求、分配給Container
- Host:代表主機域名IP(不同IP會通過DNS映射到同一個網站地址)
- Context:web應用,在域名上在進行劃分,對應到不同資源地址
- wrapper(表示Servlet):對資源地址鏈接請求進行包裝
ps:通用概念上的Container包含Engine、Host、Context、wrapper
- 一個Tomcat可以包含多個Server(tomcat實例)。
- 一個Server可以包含多個Service,每一個Service都是獨立的,他們共享一個JVM以及系統類庫。
- 一個Service負責維護多個Connector和一個Container,這樣來自Connector的請求只能由Service維護的一個Container處理。
- 一個Engine可以包含多個Host。
- 一個Host可以包含多個Context。
- 一個Context(web應用)可以包含多個wrapper(Servlet)。
1.2整體架構
- 將service抽象爲Connector和Engine,
- Connector通過EndPoint監聽端口接收請求,通過ProtocoHandler進行解析請求,並且將響應返回給客戶端,
- Service將web應用註冊到一個mapper表裏(註冊MapperLinstener,默認每隔30s掃描一次容器,會進行註冊到mapper裏),
- Service通過映射表請求到對應的web應用,交給容器通過責任鏈模式執行.....
- 最終,整個架構還融合了Executor線程池,以及容器的LifeCycle。
1.3初始化過程
- Bootstrap,初始化類加載器--common類加載器【catalina和share類加載器都會默認使用父類common類加載器,需要配置】和創建啓動類catalina對象,並執行catalina的load方法;
- Catalina,通過digester【基於SAX解析事件驅動回調實現】解析xml,並且初始化Server;
- Server,初始化多個Service;
- Service,依次初始化 Engine,executor,MapperListener【映射請求地址的監聽器】,Connector【Host、Context、Wrapper三個執行器是在start開始時纔會被初始化】;
- Connector,初始化protocolHandler【HTTP1.1】,給protocolHandler設置CoyoteAdapter適配器等等;
- protocolHandler,初始化EndPoint進行socket綁定端口【NioEndPoint】;
1.4啓動過程【調用Catalina對象的strat方法】
- Catalina,調用start方法啓動Server
- Server,啓動多個Service
- Service,啓動Engine、啓動executor、啓動MapperListener、啓動Connector
- engine,啓動cluster,啓動realm,啓動子容器【children.start()】,啓動pipeline,啓動線程
- host,啓動cluster,啓動realm,啓動子容器【children.start()】,啓動pipeline,啓動線程
- context,直到沒有子容器爲止,也就是到Wrapper(Servlet)爲止....
host主要做了(war,配置server.xml,目錄)部署方式的解析配置,
context主要是加載整個web項目資源(web.xml,拿到servlet、filter、linstener),
wrapper主要是項目底下的servlet;
1.5web請求和處理
- 發送一個請求,NioEndPoint進行監聽,
- socketChannel#accept阻塞的接收請求,
- Poller會將請求連接socketChannel設置爲非阻塞,註冊到selector中,
- Poller線程selector#select選出IO準備就緒的連接,通過線程池來執行,
- Http11Processor的service方法,實際會調用CoyoteAdaptor的service方法
- CoyoteAdaptor先解析請求,並且會通過map找到對應容器,調用StandardEngineValve的invoke方法進行處理
- 通過責任鏈模式Engine選擇一個Host,Host選擇一個Context,Context選擇一個Wrapper
ps:容器的獲取都是通過map進行查找的,在解析請求的過程中會進行設置。
- 最終,Wrapper還會創建一個過濾鏈並且進行調用
2.server.xml 配置詳解
2.1server節點
root元素:server 的頂級配置
主要屬性:
port:執行關閉命令的端口號 默認8005
shutdown:關閉命令
- 演示shutdown的用法 telent 127.0.0.1 8005 SHUTDOWN
2.2service節點
- 服務:將多個connector 與一個Engine組合成一個服務,可以配置多個服務。
2.3Connector節點
連接器:用於接收 指定協議下的連接 並指定給唯一的Engine 進行處理。
主要屬性:
- protocol 監聽的協議,默認是http/1.1,長連接
- port 指定服務器端要創建的端口號
- minThread 服務器啓動時創建的處理請求的線程數
- maxThread 最大可以創建的處理請求的線程數
- enableLookups 如果爲true,則可以通過調用request.getRemoteHost()進行DNS查詢來得到遠程客戶端的實際主機名,若爲false則不進行DNS查詢,而是返回其ip地址
- redirectPort 指定服務器正在處理http請求時收到了一個SSL傳輸請求後重定向的端口號
- acceptCount 指定當所有可以使用的處理請求的線程數都被使用時,可以放到處理隊列中的請求數,超過這個數的請求將不予處理
- connectionTimeout 指定超時的時間數(以毫秒爲單位)
- SSLEnabled 是否開啓 sll 驗證,在Https 訪問時需要開啓。
2.4Engine
引擎:用於處理連接的執行器,默認的引擎是catalina。一個service 中只能配置一個Engine。
主要屬性:name 引擎名稱 defaultHost 默認host。
2.5Host
虛擬主機:基於域名匹配至指定虛擬主機。默認的虛擬機是localhost。
主要屬性:
- 演示配置多個Host
<Host name="www.luban.com" appBase="/usr/www/luban"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="www.luban.com.access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
2.6Context
應用上下文:一個host 下可以配置多個Context ,每個Context 都有其獨立的classPath。相互隔離,以免造成ClassPath 衝突。
主要屬性:
- 演示配置多個Context
<Context docBase="hello" path="/h" reloadable="true"/>
ps:appBase會和docBase進行資源路徑拼接。
2.7Valve
閥門:可以理解成request 的過濾器,具體配置要基於具體的Valve 接口的子類。以下即爲一個訪問日誌的Valve.
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="www.luban.com.access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
ps:Engine---Host---Context---Wrapper就是基於Valve的責任鏈模式。
3.tomcat網絡模型
3.1Tomcat 支持四種線程模型介紹
BIO |
jdk1.4 之前 同步阻塞式IO,即Tomcat使用傳統的java.io進行操作。該模式下每個請求都會創建一個線程,系統瓶頸耗費在等待i/o上,不適合高併發場景。適合連接數目小且固定架構。 |
NIO |
同步非阻塞式IO,jdk1.4 之後實現的新IO。該模式基於多路複用選擇器selector監測,在通過channle以及buffer從而達到非阻塞的目的,並且更高效。Tomcat 8.0之後默認採用該模式 |
APR |
全稱是 Apache Portable Runtime/Apache可移植運行庫),是Apache HTTP服務器的支持庫。APR的整體模式還是非阻塞IO,實現的線程模型也是按照NIO的標準模型實現的,可以看到APR根據不同操作系統,分別用c重寫了大部分IO和系統線程操作模塊 |
AIO (asynchronous I/O) |
異步非阻塞式IO,jdk1.7後之支持 。與nio不同在於不需要多路複用選擇器,而是請求處理線程執行完程進行回調調知,已繼續執行後續操作。Tomcat 8之後支持。 |
使用指定IO模型的配置方式:
配置 server.xml 文件當中的 <Connector protocol="HTTP/1.1"> 修改即可。
默認配置: protocol=“HTTP/1.1” 8.0 之前是 BIO ,8.0 之後是NIO
BIO:protocol=“org.apache.coyote.http11.Http11Protocol“
NIO:protocol=”org.apache.coyote.http11.Http11NioProtocol“
AIO:protocol=”org.apache.coyote.http11.Http11Nio2Protocol“
APR:protocol=”org.apache.coyote.http11.Http11AprProtocol“
3.2Tomcat connector 併發參數解讀
acceptCount |
等待最大隊列 |
address |
綁定客戶端特定地址,127.0.0.1 |
bufferSize |
每個請求的緩衝區大小。 bufferSize * maxThreads |
compression |
是否啓用文檔壓縮 |
compressableMimeTypes |
text/html,text/xml,text/plain |
connectionTimeout |
客戶發起鏈接 到 服務端接收爲止,中間最大的等待時間 |
connectionUploadTimeout |
upload 情況下連接超時時間 |
disableUploadTimeout |
true 則使用connectionTimeout |
enableLookups |
禁用DNS查詢 true |
keepAliveTimeout |
當長鏈接閒置 指定時間主動關閉 鏈接 ,前提是客戶端請求頭 帶上這個 head"connection" " keep-alive" |
maxKeepAliveRequests |
最大的 長連接數 |
maxHttpHeaderSize |
|
maxSpareThreads |
BIO 模式下 最多線閒置線程數 |
maxThreads(執行線程) |
最大執行線程數 |
minSpareThreads(初始線業務線程 10) |
BIO 模式下 最小線閒置線程數 |