Tomcat生產環境應用
概要:
- 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