6道tomcat面試題,最後兩道難倒我了
即將進入金三銀四的黃金時段,所以很多人已經開始準備自己的面試抱佛腳了。今天我整理了6道關於tomcat的核心面試題以及參看答案,看完對於絕大多數人應對面試妥妥的。
1、Tomcat的預設埠是多少,怎麼修改?
預設埠為8080,可以通過在tomcat安裝包conf目錄下,service.xml中的Connector元素的port屬性來修改埠。
2、tomcat 有哪幾種Connector 執行模式(優化)?
這三種模式的不同之處如下:
BIO:一個執行緒處理一個請求。缺點:併發量高時,執行緒數較多,浪費資源。Tomcat7版本或更低版本中,在Linux系統中預設使用這種方式。
NIO:利用Java的非同步IO處理,可以通過少量的執行緒處理大量的請求。tomcat8.0.x中預設使用的是NIO。Tomcat7必須修改Connector配置來啟動:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443"/>
APR:即Apache Portable Runtime,從作業系統層面解決io阻塞問題。Tomcat7或Tomcat8在Win7或以上的系統中啟動預設使用這種方式。
3、Tomcat有幾種部署方式?
- 利用Tomcat的自動部署:把web應用拷貝到webapps目錄(生產環境不建議放在該目錄中)。Tomcat在啟動時會載入目錄下的應用,並將編譯後的結果放入work目錄下。
- 使用Manager App控制檯部署:在tomcat主頁點選“Manager App” 進入應用管理控制檯,可以指定一個web應用的路徑或war檔案。
- 修改conf/server.xml檔案部署:在server.xml檔案中,增加Context節點可以部署應用。
- 增加自定義的Web部署檔案:在conf/Catalina/localhost/路徑下增加 xyz.xml檔案,內容是Context節點,可以部署應用。
4、tomcat容器是如何建立servlet類例項?用到了什麼原理?
- 當容器啟動時,會讀取在webapps目錄下所有的web應用中的web.xml檔案,然後對 xml檔案進行解析,並讀取servlet註冊資訊。然後,將每個應用中註冊的servlet類都進行載入,並通過 反射的方式例項化。(有時候也是在第一次請求時例項化)
- 在servlet註冊時加上1如果為正數,則在一開始就例項化,如果不寫或為負數,則第一次請求例項化。
5、tomcat 如何優化?
tomcat作為Web伺服器,它的處理效能直接關係到使用者體驗,下面是幾種常見的優化措施:
掉對web.xml的監視,把jsp提前編輯成Servlet。有富餘實體記憶體的情況,加大tomcat使用的jvm的記憶體
伺服器所能提供CPU、記憶體、硬碟的效能對處理能力有決定性影響。
- 對於高併發情況下會有大量的運算,那麼CPU的速度會直接影響到處理速度。
- 記憶體在大量資料處理的情況下,將會有較大的記憶體容量需求,可以用-Xmx -Xms -XX:MaxPermSize等引數對記憶體不同功能塊進行劃分。我們之前就遇到過記憶體分配不足,導致虛擬機器一直處於full GC,從而導致處理能力嚴重下降。
- 硬碟主要問題就是讀寫效能,當大量檔案進行讀寫時,磁碟極容易成為效能瓶頸。最好的辦法還是利用下面提到的快取。
利用快取和壓縮
- 對於靜態頁面最好是能夠快取起來,這樣就不必每次從磁碟上讀。這裡我們採用了Nginx作為快取伺服器,將圖片、css、js檔案都進行了快取,有效的減少了後端tomcat的訪問。
- 另外,為了能加快網路傳輸速度,開啟gzip壓縮也是必不可少的。但考慮到tomcat已經需要處理很多東西了,所以把這個壓縮的工作就交給前端的Nginx來完成。
- 除了文字可以用gzip壓縮,其實很多圖片也可以用影象處理工具預先進行壓縮,找到一個平衡點可以讓畫質損失很小而檔案可以減小很多。曾經我就見過一個圖片從300多kb壓縮到幾十kb,自己幾乎看不出來區別。
採用叢集
單個伺服器效能總是有限的,最好的辦法自然是實現橫向擴充套件,那麼組建tomcat叢集是有效提升效能的手段。我們還是採用了Nginx來作為請求分流的伺服器,後端多個tomcat共享session來協同工作。可以參考之前寫的《利用nginx+tomcat+memcached組建web伺服器負載均衡》。
優化執行緒數優化
找到Connector port="8080" protocol="HTTP/1.1",增加maxThreads和acceptCount屬性(使acceptCount大於等於maxThreads),如下:
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000" redirectPort="8443"acceptCount="500" maxThreads="400" />
其中:
• maxThreads:tomcat可用於請求處理的最大執行緒數,預設是200
• minSpareThreads:tomcat初始執行緒數,即最小空閒執行緒數
• maxSpareThreads:tomcat最大空閒執行緒數,超過的會被關閉
• acceptCount:當所有可以使用的處理請求的執行緒數都被使用時,可以放到處理佇列中的請求數,超過這個數的請求將不予處理.預設100
使用執行緒池優化
在server.xml中增加executor節點,然後配置connector的executor屬性,如下:
<Executor name="tomcatThreadPool" namePrefix="req-exec-"maxThreads="1000" minSpareThreads="50"maxIdleTime="60000"/>
<Connector port="8080" protocol="HTTP/1.1"executor="tomcatThreadPool"/>
其中:
• namePrefix:執行緒池中執行緒的命名字首
• maxThreads:執行緒池的最大執行緒數
• minSpareThreads:執行緒池的最小空閒執行緒數
• maxIdleTime:超過最小空閒執行緒數時,多的執行緒會等待這個時間長度,然後關閉
• threadPriority:執行緒優先順序
注:當tomcat併發使用者量大的時候,單個jvm程序確實可能開啟過多的檔案控制代碼,這時會報java.net.SocketException:Too many open files錯誤。可使用下面步驟檢查:
• ps -ef |grep tomcat 檢視tomcat的程序ID,記錄ID號,假設程序ID為10001
• lsof -p 10001|wc -l 檢視當前程序id為10001的 檔案運算元
• 使用命令:ulimit -a 檢視每個使用者允許開啟的最大檔案數
啟動速度優化
- 刪除沒用的web應用:因為tomcat啟動每次都會部署這些應用。
- 關閉WebSocket:websocket-api.jar和tomcat-websocket.jar。
- 隨機數優化:設定JVM引數:-Djava.security.egd=file:/dev/./urandom。
記憶體優化
因為tomcat啟動起來後就是一個java程序,所以這塊可以參照JVM部分的優化思路。堆記憶體相關引數,比如說:
• -Xms:虛擬機器初始化時的最小堆記憶體。
• -Xmx:虛擬機器可使用的最大堆記憶體。-Xms與-Xmx設成一樣的值,避免JVM因為頻繁的GC導致效能大起大落
• -XX:MaxNewSize:新生代佔整個堆記憶體的最大值。
另外還有方法區引數調整(注意:JDK版本)、垃圾收集器等優化。JVM相關引數請看:手把手教你設定JVM調優引數
6、熟悉tomcat的哪些配置?
Context(表示一個web應用程式,通常為WAR檔案,關於WAR的具體資訊見servlet規範)標籤。
docBase:該web應用的文件基準目錄(Document Base,也稱為Context Root),或者是WAR檔案的路徑。可以使絕對路徑,也可以使用相對於context所屬的Host的appBase路徑。
path:表示此web應用程式的url的字首,這樣請求的url為http://localhost:8080/path/****。
reloadable:這個屬性非常重要,如果為true,則tomcat會自動檢測應用程式的/WEB-INF/lib和/WEB-INF/classes目錄的變化,自動裝載新的應用程式,我們可以在不重啟tomcat的情況下改變應用程式。
useNaming:如果希望Catalina為該web應用使能一個JNDI InitialContext物件,設為true。該InitialialContext符合J2EE平臺的約定,預設值為true。
workDir:Context提供的臨時目錄的路徑,用於servlet的臨時讀/寫。利用javax.servlet.context.tempdir屬性,servlet可以訪問該目錄。如果沒有指定,使用$CATALINA_HOME/work下一個合適的目錄。
swallowOutput:如果該值為true,System.out和System.err的輸出被重定向到web應用的logger。如果沒有指定,預設值為false
debug:與這個Engine關聯的Logger記錄的除錯資訊的詳細程度。數字越大,輸出越詳細。如果沒有指定,預設為0。
host(表示一個虛擬主機)標籤。
name:指定主機名。
appBase:應用程式基本目錄,即存放應用程式的目錄。
unpackWARs:如果為true,則tomcat會自動將WAR檔案解壓,否則不解壓,直接從WAR檔案中執行應用程式。
Logger(表示日誌,除錯和錯誤資訊)標籤。
className:指定logger使用的類名,此類必須實現org.apache.catalina.Logger介面。
prefix:指定log檔案的字首。
suffix:指定log檔案的字尾。
timestamp:如果為true,則log檔名中要加入時間,如下例:localhost_log.2001-10-04.txt。
總結
本文一共六道關於tomcat的題目:
- Tomcat的預設埠是多少,怎麼修改?
- tomcat 有哪幾種Connector 執行模式(優化)?
- Tomcat有幾種部署方式?
- tomcat容器是如何建立servlet類例項?用到了什麼原理?
- tomcat 如何優化?熟悉tomcat的哪些配置?
再次回頭想想你會幾道呢?
「做人可以沒天賦,但不能沒鬥志。」