概要:
- Tomcat各核心組件認知
- Tomcat server.xml 配置詳解
- Tomcat IO模型介紹
一、Tomcat各組件認知
知識點:
- Tomcat架構說明
- Tomcat組件及關係詳情介紹
- Tomcat啓動參數說明
一 Tomcat架構說明
Tomcat是一個基於JAVA的WEB容器,其實現了JAVA EE中的 Servlet 與 jsp 規範,與Nginx apache 服務器不同在於一般用於動態請求處理。在架構設計上採用面向組件的方式設計。即整體功能是通過組件的方式拼裝完成。另外每個組件都可以被替換以保證靈活性。
那麼是哪些組件組成了Tomcat呢?
2.Tomcat 各組件及關係
- Server 和 Service
- Connector 連接器
- HTTP 1.1
- SSL https
- AJP( Apache JServ Protocol) apache 私有協議,用於apache 反向代理Tomcat
- Container
- Engine 引擎 catalina
- Host 虛擬機 基於域名 分發請求
- Context 隔離各個WEB應用 每個Context的 ClassLoader都是獨立
- Component
- Manager (管理器)
- logger (日誌管理)
- loader (載入器)
- pipeline (管道)
- valve (管道中的閥)
3.Tomcat啓動參數說明
我們平時啓動Tomcat過程是怎麼樣的?
- 複製WAR包至Tomcat webapp 目錄。
- 執行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 |
可以編寫一個腳本 來實現自定義配置:
演示自定義啓動Tomcat
- 下載並解壓Tomcat
- 創建並拷貝應用目錄
- 創建Tomcat.sh
- 編寫Tomcat.sh
- chmod +x tomcat.sh 添加執行權限
- 拷貝conf 、webapps 、logs至應用目錄。
- 執行啓動測試。
#!/bin/bash
export JAVA_OPTS="-Xms100m -Xmx200m"
export JAVA_HOME=/root/svr/jdk/
export CATALINA_HOME=/usr/local/apache-tomcat-8.5.34
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 2
$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
上面是tomcat啓動和停止,重啓和版本查看腳本
二、Tomcat server.xml 配置詳解
Server 的基本基本配置:
<Server>
<Listener /><!-- 監聽器 -->
<GlobaNamingResources> <!-- 全局資源 -->
</GlobaNamingResources
<Service> <!-- 服務 用於 綁定 連接器與 Engine -->
<Connector 8080/> <!-- 連接器-->
<Connector 8010 /> <!-- 連接器-->
<Connector 8030/> <!-- 連接器-->
<Engine> <!-- 執行引擎-->
<Logger />
<Realm />
<host "www.tl.com" appBase=""> <!-- 虛擬主機-->
<Logger /> <!-- 日誌配置-->
<Context "/luban" path=""/> <!-- 上下文配置-->
</host>
</Engine>
</Service>
</Server>
上面是server.xml 片段配置詳解
元素說明:
server
root元素:server 的頂級配置
主要屬性:
port:執行關閉命令的端口號
shutdown:關閉命令
- 演示shutdown的用法
#基於telent 執行SHUTDOWN 命令即可關閉
telent 127.0.0.1 8005
SHUTDOWN
service
服務:將多個connector 與一個Engine組合成一個服務,可以配置多個服務。
Connector
連接器:用於接收 指定協議下的連接 並指定給唯一的Engine 進行處理。
主要屬性:
- protocol 監聽的協議,默認是http/1.1
- port 指定服務器端要創建的端口號
- minThread服務器啓動時創建的處理請求的線程數
- maxThread最大可以創建的處理請求的線程數
- enableLookups如果爲true,則可以通過調用request.getRemoteHost()進行DNS查詢來得到遠程客戶端的實際主機名,若爲false則不進行DNS查詢,而是返回其ip地址
- redirectPort指定服務器正在處理http請求時收到了一個SSL傳輸請求後重定向的端口號
- acceptCount指定當所有可以使用的處理請求的線程數都被使用時,可以放到處理隊列中的請求數,超過這個數的請求將不予處理
- connectionTimeout指定超時的時間數(以毫秒爲單位)
- SSLEnabled 是否開啓 sll 驗證,在Https 訪問時需要開啓。
- 演示配置多個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"
enableLookups="false"
/>
Engine
引擎:用於處理連接的執行器,默認的引擎是catalina。一個service 中只能配置一個Engine。
主要屬性:name 引擎名稱 defaultHost 默認host
Host
虛擬機:基於域名匹配至指定虛擬機。類似於nginx 當中的server,默認的虛擬機是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>
Context
應用上下文:一個host 下可以配置多個Context ,每個Context 都有其獨立的classPath。相互隔離,以免造成ClassPath 衝突。
主要屬性:
- 演示配置多個Context
<Context docBase="hello" path="/h" reloadable="true"/>
Valve
閥門:可以理解成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" />
三、Tomcat IO模型介紹
知識點:
- Tomcat支持的IO模型說明
- BIO 與NIO的區別
- IO模型源碼解讀
1、Tomcat支持的IO模型說明
|
描述 |
BIO |
阻塞式IO,即Tomcat使用傳統的java.io進行操作。該模式下每個請求都會創建一個線程,對性能開銷大,不適合高併發場景。優點是穩定,適合連接數目小且固定架構。 |
NIO |
非阻塞式IO,jdk1.4 之後實現的新IO。該模式基於多路複用選擇器監測連接狀態在通知線程處理,從而達到非阻塞的目的。比傳統BIO能更好的支持併發性能。Tomcat 8.0之後默認採用該模式 |
APR |
全稱是 Apache Portable Runtime/Apache可移植運行庫),是Apache HTTP服務器的支持庫。可以簡單地理解爲,Tomcat將以JNI的形式調用Apache HTTP服務器的核心動態鏈接庫來處理文件讀取或網絡傳輸操作。使用需要編譯安裝APR 庫 |
AIO |
異步非阻塞式IO,jdk1.7後之支持 。與nio不同在於不需要多路複用選擇器,而是請求處理線程執行完程進行回調調知,已繼續執行後續操作。Tomcat 8之後支持。 |
|
|
使用指定IO模型的配置方式:
配置 server.xml 文件當中的 <Connector protocol="HTTP/1.1"> 修改即可。
默認配置 8.0 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“
2、BIO 與NIO有什麼區別
分別演示在高併發場景下BIO與NIO的線程數的變化?
演示數據:
|
每秒提交數 |
BIO執行線程 |
NIO執行線程 |
|
預測 |
200 |
200 |
50 |
|
實驗環境 |
200 |
48 |
37 |
|
生產環境 |
200 |
419 |
23 |
|
結論:NIO比BIO牛逼
BIO 線程模型講解
NIO 線程模型講解
BIO 源碼解讀
- Http11Protocol Http BIO協議解析器
- JIoEndpoint
- Acceptor implements Runnable
- SocketProcessor implements Runnable
- JIoEndpoint
- Http11NioProtocol Http Nio協議解析器
- NioEndpoint
- Acceptor implements Runnable
- Poller implements Runnable
- SocketProcessor implements Runnable
- NioEndpoint