時間:2023-07-12 08:24:02 | 來源:網(wǎng)站運(yùn)營
時間:2023-07-12 08:24:02 來源:網(wǎng)站運(yùn)營
程序猿必須知道的關(guān)于 Tomcat 的知識點(diǎn):Java
程序員,Tomcat
應(yīng)該算是我們接觸的最多的 web
容器了。同時,作為企業(yè)生產(chǎn)工具的 “八阿哥”
們,平常只顧著埋頭寫 BUG
,哪有什么時間整理用過的知識點(diǎn)。今天,我將和大家一起梳理一下關(guān)于 Tomcat
的相關(guān)內(nèi)容,由淺入深,從入門到放棄。奧利給~!TCP
連接請求。TCP
連接。(基于 Socket
實(shí)現(xiàn))HTTP
格式的數(shù)據(jù)包。TCP
請求數(shù)據(jù)包。(這個數(shù)據(jù)包的請求頭為 TCP
格式的請求頭,上一步封裝的HTTP
格式的數(shù)據(jù)包被作為 TCP
請求體傳送至服務(wù)器)TCP
請求體中的 HTTP
數(shù)據(jù)包。HTTP
格式的響應(yīng)數(shù)據(jù)包。HTTP
格式的響應(yīng)數(shù)據(jù)包。(解析出的數(shù)據(jù)為靜態(tài)數(shù)據(jù)如:HTML
、CSS
、JS
、圖片等)Tomcat
作為 Servlet
容器從軟件運(yùn)行角度看,主要可以分為兩大模塊,一個是 Http
請求接收、響應(yīng)模塊(Coyote
),另一個是請求處理模塊,即從 Servlet
容器中獲取與請求對應(yīng)的處理方法并執(zhí)行(Catalina
)。Coyote
連接器包含以下兩個模塊:ProtocolHandler
協(xié)議處理接口。這個接口通過 Endpoint
和 Processor
,實(shí)現(xiàn)針對具體協(xié)議的處 理能?。Tomcat
按照協(xié)議和 I/O
提供了6個實(shí)現(xiàn)類 : AjpNioProtocol
,AjpAprProtocol
,AjpNio2Protocol
, Http11NioProtocol
,Http11Nio2Protocol
,Http11AprProtocol
Processor
?來實(shí)現(xiàn) HTTP
協(xié)議,可將來? EndPoint
的 Socket
,讀取字節(jié)流解析成 Tomcat
自己定義的 Request
和 Response
對象。Processor
是對應(yīng)?層協(xié)議的抽象(注意:這里的 Tomcat Request
和 Response
對象,還不是我們在 Servlet
中所用到的 ServletRequest
和 ServletResponse
對象。)Adapter
由于請求協(xié)議的不同,客戶端發(fā)送至后臺的請求信息也不盡相同。為了能夠轉(zhuǎn)換成統(tǒng)一的 ServletRequest
和 ServletResponse
對象方便 Servlet
容器處理業(yè)務(wù),則需要該接口的實(shí)現(xiàn)類,對發(fā)送至 Tomcat
的請求進(jìn)行統(tǒng)一的適配處理。進(jìn)而使調(diào)用 Servlet
容器中的方法變的簡單。Servlet
容器又名 Catalina
。一個 Catalina
實(shí)例只能擁有一個 Server
實(shí)例,一個 Server
實(shí)例可以包含多個 Service
實(shí)例。而每一個 Service
實(shí)例又可以包含多個 Connector
和一個 Container
。一個 Container
只能有一個 Engine
,一個 Engine
可以有多個 Host
,每個 Host
可以包含多個 Context
(網(wǎng)站),每個 Context
中可以有多個 Wrapper
(Servlet
)。Catalina
實(shí)例可以被看成就是一個 Tomcat
實(shí)例。該實(shí)例用以解析 server.xml
配置文件, 以此來創(chuàng)建服務(wù)器Server組件并進(jìn)?管理。Server
表示整個 Catalina Servlet
容器以及其它組件,負(fù)責(zé)組裝并啟動 Servlaet
引擎,Tomcat
連接器。Service
是 Server
內(nèi)部的組件,?個 Server
包含多個 Service
。它將若?個 Connector
組件綁定到?個 Container
。(通常情況下只用一個 Service
就夠了)Container
負(fù)責(zé)處理?戶的 servlet
請求,并將處理結(jié)果返回給用戶。Engine
是整個 Catalina
的 Servlet
引擎,?來管理多個虛擬站點(diǎn),?個 Service
最多只能有?個 Engine
,但是?個 Engine
可包含多個 Host
。Host
代表?個虛擬主機(jī),或者說?個站點(diǎn),可以給 Tomcat
配置多個虛擬主機(jī)地址。??個虛擬主機(jī)下可包含多個 Context
。Context
表示?個 Web
應(yīng)?程序, ?個 Web
應(yīng)?可包含多個 Wrapper
。Wrapper
表示?個 Servlet
。Wrapper
作為容器中的最底層,不能包含?容器。Tomcat
軟件中的 conf/server.xml
里。Tomcat
的配置文件 server.xml
時,你的第一感受是啥?反正我最真切的感受就是:“我靠,英文真多~!”。不過靜下心來再看,更多的都是說明性文字。刪除注釋后再看,就跟被拔光毛的雞一樣,也就那樣。不信你看 <?xml version="1.0" encoding="UTF-8"?><!-- port:關(guān)閉服務(wù)器的監(jiān)聽端? shutdown:關(guān)閉服務(wù)器的指令字符串 --><Server port="8005" shutdown="SHUTDOWN"> <!-- 以?志形式輸出服務(wù)器 、操作系統(tǒng)、JVM的版本信息 --> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <!-- 加載(服務(wù)器啟動)和銷毀(服務(wù)器停?)APR。如果找不到 APR 庫,則會輸出?志,但并不影響 Tomcat 啟動 --> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <!-- 避免JRE內(nèi)存泄漏問題 --> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <!-- 加載(服務(wù)器啟動)和銷毀(服務(wù)器停?)全局命名服務(wù) --> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <!-- 在Context停?時重建 Executor 池中的線程,以避免 ThreadLocal 相關(guān)的內(nèi)存泄漏 --> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <!-- 全局命名服務(wù),定義服務(wù)器的全局 JNDI 資源 --> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <!-- 處理 HTTP/1.1 協(xié)議的請求 --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- 處理 AJP/1.3 協(xié)議的請求 用不到的話可以注釋掉 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" /> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service></Server>
這么一整理是不是瞬間清爽了很多。需要注意的是,通常情況下,上面配置文件里添加了注釋的部分,除了 Connector
標(biāo)簽中的參數(shù),其他標(biāo)簽的內(nèi)容一般不需要修改,保持默認(rèn)即可。<Service name="Catalina"> ...</Service>
該標(biāo)簽?于創(chuàng)建 Service
實(shí)例,默認(rèn)使? org.apache.catalina.core.StandardService
對象。默認(rèn)情況下,Tomcat
僅指定了 Service
的名稱, 值為 "Catalina
"。 Service
?標(biāo)簽有 : Listener
、Executor
、Connector
、Engine
。其中:Listener
?于為 Service
添加?命周期監(jiān)聽器(用的比較少,故下文不做說明)Executor
?于配置 Service
共享線程池Connector
?于配置 Service
包含的鏈接器Engine
?于配置 Service
中鏈接器對應(yīng)的 Servlet
容器引擎Service
添加線程池。默認(rèn)情況下,在 server.xml
文件中,該標(biāo)簽是被注釋掉的,即未開啟線程池的。如果想開啟,則打開注釋,并配置相關(guān)屬性即可。<Executor name="commonThreadPool" namePrefix="thread-exec-" maxThreads="200" minSpareThreads="100" maxIdleTime="60000" maxQueueSize="Integer.MAX_VALUE" prestartminSpareThreads="false" threadPriority="5" className="org.apache.catalina.core.StandardThreadExecutor"/>
<Executor> 標(biāo)簽屬性含義:name
:線程池名稱。通過該屬性的值,可在 <Connector>
標(biāo)簽中指定對應(yīng)線程池。namePrefix
:所創(chuàng)建的每個線程的名稱前綴,?個單獨(dú)的線程名稱為:namePrefix + threadNumber
。maxThreads
:線程池中最?線程數(shù)。minSpareThreads
:最小空閑線程數(shù),即活躍線程數(shù),也就是核?池線程數(shù)。這些線程不會被銷毀,會?直存在。maxIdleTime
:線程空閑時間,超過該時間后,空閑線程會被銷毀,默認(rèn)值為 6000
(1分鐘),單位毫秒。maxQueueSize
:在被執(zhí)?前最?線程排隊(duì)數(shù)?,默認(rèn)為 Int
的最?值,也就是?義的?限。除?特殊情況,否則這個值不需要更改,不然會有請求不會被處理的情況發(fā)?。prestartminSpareThreads
:啟動線程池時是否啟動 minSpareThreads
部分線程。默認(rèn)值為 false
,即不啟動。threadPriority
:線程池中線程優(yōu)先級,默認(rèn)值為 5
,值從 1
到 10
。className
:線程池實(shí)現(xiàn)類,未指定情況下,默認(rèn)實(shí)現(xiàn)類為org.apache.catalina.core.StandardThreadExecutor
。如果想使??定義線程池?先需要實(shí)現(xiàn)org.apache.catalina.Executor
接?。server.xml
配置了兩個鏈接器,?個?持 HTTP
協(xié)議,?個?持 AJP
協(xié)議?多數(shù)情況下,我們并不需要新增鏈接器配置,只是根據(jù)需要對已有鏈接器進(jìn)?優(yōu)化。<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" executor="commonThreadPool" URIEncoding="UTF-8" minSpareThreads="100" maxThreads="1000" acceptCount="1000" maxConnections="1000" compression="on" compressionMinSize="2048" disableUploadTimeout="true" />
<Connector> 標(biāo)簽屬性含義:port
:端?號,Connector
?于創(chuàng)建服務(wù)端 Socket
并進(jìn)?監(jiān)聽, 以等待客戶端請求鏈接。如果該屬性設(shè)置為 0
,Tomcat
將會隨機(jī)選擇?個可?的端?號給當(dāng)前 Connector
使?。protocol
:當(dāng)前 Connector
?持的訪問協(xié)議。 默認(rèn)為 HTTP/1.1
,并采??動切換機(jī)制選擇?個基于JAVA NIO
的鏈接器或者基于本地 APR
的鏈接器。(若想使用 APR
提高 Tomcat
的并發(fā)性能,則需要安裝相關(guān)運(yùn)行庫后,再進(jìn)行配置修改)connectionTimeOut
:Connector
接收鏈接后的等待超時時間, 單位為 毫秒。 -1 表示不超時。redirectPort
:當(dāng)前 Connector
不?持 SSL
請求。如果接收到了?個請求, 且同時符合 security-constraint
約束,需要 SSL
傳輸,Catalina
則會?動將請求重定向到指定的端?。executor
:指定要使用的共享線程池的名稱。URIEncoding
:?于指定編碼 URI
的字符編碼,Tomcat8.x
版本默認(rèn)的編碼為 UTF-8
, Tomcat7.x
版本默認(rèn)為 ISO-8859-1
。executor
屬性),選擇讓每一個 Connector
單獨(dú)維護(hù)自己的線程池時可通過 maxThreads
、minSpareThreads
、acceptCount
、maxConnections
進(jìn)行 Connector
線程池的配置。需要注意的是 maxThreads
、acceptCount
、maxConnections
這三個屬性的值通常保持一致。compression
:是否開啟數(shù)據(jù)請求等的 gzip
格式壓縮。compressionMinSize
:最小壓縮大小,即當(dāng)數(shù)據(jù)請求超過指定值后才會進(jìn)行壓縮。disableUploadTimeout
:允許 Servlet
容器,使用較長的連接超時值,以使 Servlet
有較長的時間來完成它的執(zhí)行,默認(rèn)值為 false
。<Engine name="Catalina" defaultHost="localhost"> ...</Engine>
該標(biāo)簽表示 Servlet
引擎。其屬性 name
?于指定 Engine
的名稱, 默認(rèn)為Catalina
。defaultHost
屬性用于指定默認(rèn)使?的虛擬主機(jī)名稱,當(dāng)客戶端請求指向的主機(jī)?效時,將交由默認(rèn)的虛擬主機(jī)處理,默認(rèn)為值 localhost
。<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> ...</Host>
該標(biāo)簽用于配置?個虛擬主機(jī)。name
:指定虛擬主機(jī)的名稱。appBase
:指定引用基礎(chǔ)目錄。unpackWARs
:是否自動解壓 war
包。autoDeploy
:當(dāng)資源有變更時是否自動部署。<Host name="www.abc.com" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docBase="/Users/yingdian/web_demo" path="/web_demo"></Context> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /></Host>
<Host>
標(biāo)簽中的 <Context>
標(biāo)簽用于配置一個 Web
應(yīng)用。docBase
:指定 Web
應(yīng)??錄或者 War
包的部署路徑??梢允墙^對路徑,也可以是相對于 Host appBase
的相對路徑。(appBase
的子目錄)path
:Web
應(yīng)?的 URL
訪問路徑。如上所示,我們 Host
名為 www.abc.com
, 則該 Web
應(yīng)?訪問的根路徑為:http://www.abc.com:8080/web_demo
。JDK
中的 keytool
?具?成免費(fèi)的秘鑰庫?件(證書)。keytool -genkey -alias SupremeSir -keyalg RSA -keystore supreme.keystore
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" schema="https" secure="true" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="E:/**/apache-tomcat/bin/supreme.keystore" certificateKeystorePassword="123456" type="RSA"/> </SSLHostConfig></Connector>
certificateKeystoreFile
:指定證書所在位置。certificateKeystorePassword
:指定證書秘鑰庫口令。Tomcat
優(yōu)化沒有明確的參數(shù)值可以直接去使?,必須根據(jù)??的真實(shí)?產(chǎn)環(huán)境來進(jìn)?調(diào)整,調(diào)優(yōu)是?個過程。調(diào)優(yōu)主要從兩個??進(jìn)?:JVM
虛擬機(jī)優(yōu)化(優(yōu)化內(nèi)存模型)Tomcat
?身配置的優(yōu)化參數(shù) | 參數(shù)作用 | 優(yōu)化建議 |
---|---|---|
-server | 啟動Server,以服務(wù)端模式運(yùn)? | 服務(wù)端模式建議開啟 |
-Xms | 最?堆內(nèi)存 | 建議與-Xmx設(shè)置相同 |
-Xmx | 最?堆內(nèi)存 | 建議設(shè)置為可?內(nèi)存的80% |
-XX:MetaspaceSize | 元空間初始值 | 自行調(diào)整 |
-XX:MaxMetaspaceSize | 元空間最?內(nèi)存 | 默認(rèn)?限 |
-XX:NewRatio | 年輕代和?年代???值,取值為整數(shù),默認(rèn)為2 | 不需要修改 |
-XX:SurvivorRatio | Eden區(qū)與Survivor區(qū)??的?值,取值為整數(shù),默認(rèn)為8 | 不需要修改 |
bin/catalina.sh
的腳本中 , 追加如下配置 JAVA_OPTS="-server -Xms2048m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
Serial Collector
)Parallel Collector
)Concurrent Collector
)Concurrent Mark Sweep Collector
)Garbage-First Garbage Collector
)JDK1.7
之后)參數(shù) | 描述 |
---|---|
-XX:+UseSerialGC | 啟?串?收集器 |
-XX:+UseParallelGC | 啟?并?垃圾收集器,配置了該選項(xiàng),那么 -XX:+UseParallelOldGC默認(rèn)啟? |
-XX:+UseParNewGC | 年輕代采?并?收集器,如果設(shè)置了 -XX:+UseConcMarkSweepGC選項(xiàng),?動啟? |
-XX:ParallelGCThreads | 年輕代及?年代垃圾回收使?的線程數(shù)。默認(rèn)值依賴于JVM使?的CPU個數(shù) |
-XX:+UseConcMarkSweepGC | 對于?年代,啟?CMS垃圾收集器。 當(dāng)并?收集器?法滿?應(yīng)?的延遲需求時, 推薦使?CMS或G1收集器。啟?該選項(xiàng)后,-XX:+UseParNewGC?動啟?。 |
-XX:+UseG1GC | 啟?G1收集器。 G1是服務(wù)器類型的收集器, ?于多核、?內(nèi)存的機(jī)器。 它在保持?吞吐量的情況下,?概率滿?GC暫停時間的?標(biāo)。 |
bin/catalina.sh
的腳本中 , 追加如下配置:sh JAVA_OPTS="-XX:+UseConcMarkSweepGC"
JAVA_OPTS
中追加即可。Tomcat
線程池Tomcat
的連接器Tomcat/conf/server.xml
中關(guān)于鏈接器的配置可以提升應(yīng)?服務(wù)器的性能。參數(shù) | 說明 |
---|---|
maxConnections | 最?連接數(shù),當(dāng)?shù)竭_(dá)該值后,服務(wù)器接收但不會處理更多的請求, 額外的請求將會阻塞直到連接數(shù)低于maxConnections 。可通過ulimit -a 查看服務(wù)器限制。對于CPU要求更?(計(jì)算密集型)時,建議不要配置過? ; 對于CPU要求不是特別?時,建議配置在2000左右(受服務(wù)器性能影響)。 當(dāng)然這個需要服務(wù)器硬件的?持 |
maxThreads | 最?線程數(shù),需要根據(jù)服務(wù)器的硬件情況,進(jìn)??個合理的設(shè)置 |
acceptCount | 最?排隊(duì)等待數(shù),當(dāng)服務(wù)器接收的請求數(shù)量到達(dá)maxConnections ,此時Tomcat會將后?的請求,存放在任務(wù)隊(duì)列中進(jìn)?排序, acceptCount指的就是任務(wù)隊(duì)列中排隊(duì)等待的請求數(shù) 。 ?臺Tomcat的最?的請求處理數(shù)量,是maxConnections + acceptCount |
AJP
連接器 IO
模式Tomcat8
之前的版本默認(rèn)使? BIO
(阻塞式 IO
),對于每?個請求都要創(chuàng)建?個線程來處理,不適合?并發(fā);Tomcat8
以后的版本默認(rèn)使? NIO
模式(?阻塞式 IO
)。Tomcat
并發(fā)性能有較?要求或者出現(xiàn)瓶頸時,我們可以嘗試使? APR
模式,APR
(Apache Portable Runtime
)是從操作系統(tǒng)級別解決異步 IO
問題,使?時需要在操作系統(tǒng)上安裝 APR
和Native
(因?yàn)?APR
原理是使?使? JNI
技術(shù)調(diào)?操作系統(tǒng)底層的 IO
接?)。Nginx + Tomcat
相結(jié)合的部署?案,Nginx
負(fù)責(zé)靜態(tài)資源訪問,Tomcat
負(fù)責(zé) Jsp
等動態(tài)資 源訪問處理(因?yàn)?Tomcat
不擅?處理靜態(tài)資源)。關(guān)鍵詞:知識,程序,須知
客戶&案例
營銷資訊
關(guān)于我們
微信公眾號
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。