Tomcat 面試題彙總

1、Tomcat的缺省端口是多少,怎麼修改?

1)找到Tomcat目錄下的conf文件夾

2)進入conf文件夾裏面找到server.xml文件

3)打開server.xml文件

4)在server.xml文件裏面找到下列信息

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" uriEncoding="utf-8"/>
port="8080"改成你想要的端口

2、tomcat 有哪幾種Connector 運行模式(優化)?

bio:傳統的Java I/O操作,同步且阻塞IO。

maxThreads=”150”//Tomcat使用線程來處理接收的每個請求。這個值表示Tomcat可創建的最大的線程數。默認值200。可以根據機器的時期性能和內存大小調整,一般可以在400-500。最大可以在800左右。
minSpareThreads=”25”—Tomcat初始化時創建的線程數。默認值4。如果當前沒有空閒線程,且沒有超過maxThreads,一次性創建的空閒線程數量。Tomcat初始化時創建的線程數量也由此值設置。
maxSpareThreads=”75”–一旦創建的線程超過這個值,Tomcat就會關閉不再需要的socket線程。默認值50。一旦創建的線程超過此數值,Tomcat會關閉不再需要的線程。線程數可以大致上用 “同時在線人數每秒用戶操作次數系統平均操作時間” 來計算。
acceptCount=”100”—-指定當所有可以使用的處理請求的線程數都被使用時,可以放到處理隊列中的請求數,超過這個數的請求將不予處理。默認值10。如果當前可用線程數爲0,則將請求放入處理隊列中。這個值限定了請求隊列的大小,超過這個數值的請求將不予處理。
connectionTimeout=”20000” –網絡連接超時,默認值20000,單位:毫秒。設置爲0表示永不超時,這樣設置有隱患的。通常可設置爲30000毫秒。

nio:JDK1.4開始支持,同步阻塞或同步非阻塞IO。

指定使用NIO模型來接受HTTP請求
protocol=”org.apache.coyote.http11.Http11NioProtocol” 指定使用NIO模型來接受HTTP請求。默認是BlockingIO,配置爲protocol=”HTTP/1.1”
acceptorThreadCount=”2” 使用NIO模型時接收線程的數目

aio(nio.2):JDK7開始支持,異步非阻塞IO。
apr:Tomcat將以JNI的形式調用Apache HTTP服務器的核心動態鏈接庫來處理文件讀取或網絡傳輸操作,從而大大地 提高Tomcat對靜態文件的處理性能。
<!--
      <Connector connectionTimeout="20000" port="8000" protocol="HTTP/1.1" redirectPort="8443" uriEncoding="utf-8"/>
    -->
    <!-- protocol 啓用 nio模式,(tomcat8默認使用的是nio)(apr模式利用系統級異步io) -->
    <!-- minProcessors最小空閒連接線程數-->
    <!-- maxProcessors最大連接線程數-->
    <!-- acceptCount允許的最大連接數,應大於等於maxProcessors-->
    <!-- enableLookups 如果爲true,requst.getRemoteHost會執行DNS查找,反向解析ip對應域名或主機名-->
    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" 
        connectionTimeout="20000"
        redirectPort="8443
        maxThreads=“500” 
        minSpareThreads=“100” 
        maxSpareThreads=“200”
        acceptCount="200"
        enableLookups="false"       
    />
其他配置
maxHttpHeaderSize="8192" http請求頭信息的最大程度,超過此長度的部分不予處理。一般8K。 
URIEncoding="UTF-8" 指定Tomcat容器的URL編碼格式。 
disableUploadTimeout="true" 上傳時是否使用超時機制 
enableLookups="false"--是否反查域名,默認值爲true。爲了提高處理能力,應設置爲false 
compression="on"   打開壓縮功能 
compressionMinSize="10240" 啓用壓縮的輸出內容大小,默認爲2KB 
noCompressionUserAgents="gozilla, traviata"   對於以下的瀏覽器,不啓用壓縮 
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 哪些資源類型需要壓縮 

3、Tomcat有幾種部署方式?

1)直接把Web項目放在webapps下,Tomcat會自動將其部署

2)在server.xml文件上配置<Context>節點,設置相關的屬性即可

3)通過Catalina來進行配置:進入到conf\Catalina\localhost文件下,創建一個xml文件,該文件的名字就是站點的名字。

編寫XML的方式來進行設置。

4、tomcat容器是如何創建servlet類實例?用到了什麼原理?

當容器啓動時,會讀取在webapps目錄下所有的web應用中的web.xml文件,然後對xml文件進行解析,

並讀取servlet註冊信息。然後,將每個應用中註冊的servlet類都進行加載,並通過反射的方式實例化。

(有時候也是在第一次請求時實例化)在servlet註冊時加上如果爲正數,則在一開始就實例化,

如果不寫或爲負數,則第一次請求實例化。

5.tomcat 如何優化?

1、優化連接配置.這裏以tomcat7的參數配置爲例,需要修改conf/server.xml文件,修改連接數,關閉客戶端dns查詢。

參數解釋:

URIEncoding=”UTF-8″ :使得tomcat可以解析含有中文名的文件的url,真方便,不像apache裏還有搞個mod_encoding,還要手工編譯

maxSpareThreads : 如果空閒狀態的線程數多於設置的數目,則將這些線程中止,減少這個池中的線程總數。

minSpareThreads : 最小備用線程數,tomcat啓動時的初始化的線程數。

enableLookups : 這個功效和Apache中的HostnameLookups一樣,設爲關閉。

connectionTimeout : connectionTimeout爲網絡連接超時時間毫秒數。

maxThreads : maxThreads Tomcat使用線程來處理接收的每個請求。這個值表示Tomcat可創建的最大的線程數,即最大併發數。

acceptCount : acceptCount是當線程數達到maxThreads後,後續請求會被放入一個等待隊列,這個acceptCount是這個隊列的大小,如果這個隊列也滿了,就直接refuse connection

maxProcessors與minProcessors : 在 Java中線程是程序運行時的路徑,是在一個程序中與其它控制線程無關的、能夠獨立運行的代碼段。它們共享相同的地址空間。多線程幫助程序員寫出CPU最 大利用率的高效程序,使空閒時間保持最低,從而接受更多的請求。

通常Windows是1000個左右,Linux是2000個左右。

useURIValidationHack:

我們來看一下tomcat中的一段源碼:

【security】

if (connector.getUseURIValidationHack()) {

String uri = validate(request.getRequestURI());

if (uri == null) {

res.setStatus(400);

res.setMessage(“Invalid URI”);

throw new IOException(“Invalid URI”);

} else {

req.requestURI().setString(uri);

// Redoing the URI decoding

req.decodedURI().duplicate(req.requestURI());

req.getURLDecoder().convert(req.decodedURI(), true);

可以看到如果把useURIValidationHack設成”false”,可以減少它對一些url的不必要的檢查從而減省開銷。

enableLookups=”false” : 爲了消除DNS查詢對性能的影響我們可以關閉DNS查詢,方式是修改server.xml文件中的enableLookups參數值。

disableUploadTimeout :類似於Apache中的keeyalive一樣

給Tomcat配置gzip壓縮(HTTP壓縮)功能

compression=”on” compressionMinSize=”2048″

compressableMimeType=”text/html,text/xml,text/JavaScript,text/css,text/plain”

HTTP 壓縮可以大大提高瀏覽網站的速度,它的原理是,在客戶端請求網頁後,從服務器端將網頁文件壓縮,再下載到客戶端,由客戶端的瀏覽器負責解壓縮並瀏覽。相對於普通的瀏覽過程HTML,CSS,javascript , Text ,它可以節省40%左右的流量。更爲重要的是,它可以對動態生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等輸出的網頁也能進行壓縮,壓縮效率驚人。

1)compression=”on” 打開壓縮功能

2)compressionMinSize=”2048″ 啓用壓縮的輸出內容大小,這裏面默認爲2KB

3)noCompressionUserAgents=”gozilla, traviata” 對於以下的瀏覽器,不啓用壓縮

4)compressableMimeType=”text/html,text/xml” 壓縮類型

最後不要忘了把8443端口的地方也加上同樣的配置,因爲如果我們走https協議的話,我們將會用到8443端口這個段的配置,對吧?

<!–enable tomcat ssl–>

<Connector port=”8443″ protocol=”HTTP/1.1URIEncoding=”UTF-8″ minSpareThreads=”25″ maxSpareThreads=”75″

enableLookups=”false” disableUploadTimeout=”true” connectionTimeout=”20000″

acceptCount=”300″ maxThreads=”300″ maxProcessors=”1000″ minProcessors=”5″

useURIValidationHack=”false”

compression=”on” compressionMinSize=”2048″

compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plainSSLEnabled=”true”

scheme=”https” secure=”true”

clientAuth=”false” sslProtocol=”TLS”

keystoreFile=”d:/tomcat2/conf/shnlap93.jkskeystorePass=”aaaaaa”

/>

好了,所有的Tomcat優化的地方都加上了。

6.內存調優

內存方式的設置是在catalina.sh中,調整一下JAVA_OPTS變量即可,因爲後面的啓動參數會把JAVA_OPTS作爲JVM的啓動參數來處理。 
具體設置如下: 
JAVA_OPTS="$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4" 
其各項參數如下: 
-Xmx3550m:設置JVM最大可用內存爲3550M。 
-Xms3550m:設置JVM促使內存爲3550m。此值可以設置與-Xmx相同,以避免每次垃圾回收完成後JVM重新分配內存。 
-Xmn2g:設置年輕代大小爲2G。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小。持久代一般固定大小爲64m,所以增大年輕代後,將會減小年老代大小。此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8-Xss128k:設置每個線程的堆棧大小。JDK5.0以後每個線程堆棧大小爲1M,以前每個線程堆棧大小爲256K。更具應用的線程所需內存大小進行調整。在相同物理內存下,減小這個值能生成更多的線程。但是操作系統對一個進程內的線程數還是有限制的,不能無限生成,經驗值在3000~5000左右。 
-XX:NewRatio=4:設置年輕代(包括Eden和兩個Survivor區)與年老代的比值(除去持久代)。設置爲4,則年輕代與年老代所佔比值爲14,年輕代佔整個堆棧的1/5 
-XX:SurvivorRatio=4:設置年輕代中Eden區與Survivor區的大小比值。設置爲4,則兩個Survivor區與一個Eden區的比值爲2:4,一個Survivor區佔整個年輕代的1/6 
-XX:MaxPermSize=16m:設置持久代大小爲16m。 
-XX:MaxTenuringThreshold=0:設置垃圾最大年齡。如果設置爲0的話,則年輕代對象不經過Survivor區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設置爲一個較大值,則年輕代對象會在Survivor區進行多次複製,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概論。 

7.垃圾回收策略調優

垃圾回收的設置也是在catalina.sh中,調整JAVA_OPTS變量。 
具體設置如下: 
JAVA_OPTS="$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k -XX:+UseParallelGC  -XX:MaxGCPauseMillis=100" 
具體的垃圾回收策略及相應策略的各項參數如下: 
串行收集器(JDK1.5以前主要的回收方式) 
-XX:+UseSerialGC:設置串行收集器 
並行收集器(吞吐量優先) 
示例: 
java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC  -XX:MaxGCPauseMillis=100 

-XX:+UseParallelGC:選擇垃圾收集器爲並行收集器。此配置僅對年輕代有效。即上述配置下,年輕代使用併發收集,而年老代仍舊使用串行收集。 
-XX:ParallelGCThreads=20:配置並行收集器的線程數,即:同時多少個線程一起進行垃圾回收。此值最好配置與處理器數目相等。 
-XX:+UseParallelOldGC:配置年老代垃圾收集方式爲並行收集。JDK6.0支持對年老代並行收集 
-XX:MaxGCPauseMillis=100:設置每次年輕代垃圾回收的最長時間,如果無法滿足此時間,JVM會自動調整年輕代大小,以滿足此值。 
-XX:+UseAdaptiveSizePolicy:設置此選項後,並行收集器會自動選擇年輕代區大小和相應的Survivor區比例,以達到目標系統規定的最低相應時間或者收集頻率等,此值建議使用並行收集器時,一直打開。 
併發收集器(響應時間優先) 
示例:java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC 
-XX:+UseConcMarkSweepGC:設置年老代爲併發收集。測試中配置這個以後,-XX:NewRatio=4的配置失效了,原因不明。所以,此時年輕代大小最好用-Xmn設置。 
-XX:+UseParNewGC: 設置年輕代爲並行收集。可與CMS收集同時使用。JDK5.0以上,JVM會根據系統配置自行設置,所以無需再設置此值。 
-XX:CMSFullGCsBeforeCompaction:由於併發收集器不對內存空間進行壓縮、整理,所以運行一段時間以後會產生“碎片”,使得運行效率降低。此值設置運行多少次GC以後對內存空間進行壓縮、整理。 
-XX:+UseCMSCompactAtFullCollection:打開對年老代的壓縮。可能會影響性能,但是可以消除碎片 

7.共享session處理

目前的處理方式有如下幾種: 
1).使用Tomcat本身的Session複製功能 
參考http://ajita.iteye.com/blog/1715312(Session複製的配置) 
方案的有點是配置簡單,缺點是當集羣數量較多時,Session複製的時間會比較長,影響響應的效率 
2).使用第三方來存放共享Session 
目前用的較多的是使用memcached來管理共享Session,藉助於memcached-sesson-manager來進行Tomcat的Session管理 
參考http://ajita.iteye.com/blog/1716320(使用MSM管理Tomcat集羣session) 
3).使用黏性session的策略 
對於會話要求不太強(不涉及到計費,失敗了允許重新請求下等)的場合,同一個用戶的session可以由nginx或者apache交給同一個Tomcat來處理,這就是所謂的session sticky策略,目前應用也比較多 
參考:http://ajita.iteye.com/blog/1848665(tomcat session sticky) 
nginx默認不包含session sticky模塊,需要重新編譯才行(windows下我也不知道怎麼重新編譯) 
優點是處理效率高多了,缺點是強會話要求的場合不合適 

8.添加JMS遠程監控

對於部署在局域網內其它機器上的Tomcat,可以打開JMX監控端口,局域網其它機器就可以通過這個端口查看一些常用的參數(但一些比較複雜的功能不支持),同樣是在JVM啓動參數中配置即可,配置如下: 
-Dcom.sun.management.jmxremote.ssl=false  -Dcom.sun.management.jmxremote.authenticate=false 
-Djava.rmi.server.hostname=192.168.71.38 設置JVM的JMS監控監聽的IP地址,主要是爲了防止錯誤的監聽成127.0.0.1這個內網地址 
-Dcom.sun.management.jmxremote.port=1090 設置JVM的JMS監控的端口 
-Dcom.sun.management.jmxremote.ssl=false 設置JVM的JMS監控不實用SSL 
-Dcom.sun.management.jmxremote.authenticate=false 設置JVM的JMS監控不需要認證

9.專業點的分析工具有

IBM ISA,JProfiler、probe 等,具體監控及分析方式去網上搜索即可

10.關於Tomcat的session數目

這個可以直接從Tomcat的web管理界面去查看即可 ;
或者藉助於第三方工具Lambda Probe來查看,它相對於Tomcat自帶的管理稍微多了點功能,但也不多 ;

11.監視Tomcat的內存使用情況

使用JDK自帶的jconsole可以比較明瞭的看到內存的使用情況,線程的狀態,當前加載的類的總量等;
JDK自帶的jvisualvm可以下載插件(如GC等),可以查看更豐富的信息。如果是分析本地的Tomcat的話,還可以進行內存抽樣等,檢查每個類的使用情況

12.打印類的加載情況及對象的回收情況

這個可以通過配置JVM的啓動參數,打印這些信息(到屏幕(默認也會到catalina.log中)或者文件),具體參數如下: 
-XX:+PrintGC:輸出形式:[GC 118250K->113543K(130112K), 0.0094143 secs] [Full GC 121376K->10414K(130112K), 0.0650971 secs] 
-XX:+PrintGCDetails:輸出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs] [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs] 
-XX:+PrintGCTimeStamps -XX:+PrintGCPrintGCTimeStamps可與上面兩個混合使用,輸出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs] 
-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中斷的執行時間。可與上面混合使用。輸出形式:Application time: 0.5291524 seconds 
-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期間程序暫停的時間。可與上面混合使用。輸出形式:Total time for which application threads were stopped: 0.0468229 seconds 
-XX:PrintHeapAtGC: 打印GC前後的詳細堆棧信息 
-Xloggc:filename:與上面幾個配合使用,把相關日誌信息記錄到文件以便分析 
-verbose:class 監視加載的類的情況 
-verbose:gc 在虛擬機發生內存回收時在輸出設備顯示信息 
-verbose:jni 輸出native方法調用的相關情況,一般用於診斷jni調用錯誤信息 

13.Tomcat一個請求的完整過程

Ng:(nginx)

upstream yy_001{
        server 10.99.99.99:8080; 
        server 10.99.99.100:8080; 

        hash $**; 

        healthcheck_enabled; 
        healthcheck_delay 3000; 
        healthcheck_timeout 1000; 
        healthcheck_failcount 2; 
        healthcheck_send 'GET /healthcheck.html HTTP/1.0' 'Host: wo.com' 'Connection: close'; 
    }

     server {
        include base.conf;
        server_name  wo.de.tian;
         ...
        location /yy/ { 
            proxy_pass http://yy_001;
        }
首先 dns 解析 wo.de.tian機器,一般是ng服務器ip地址 
然後 ng根據server的配置,尋找路徑爲 yy/的機器列表,ip和端口 
最後 選擇其中一臺機器進行訪問—->下面爲詳細過程

1) 請求被髮送到本機端口8080,被在那裏偵聽的Coyote HTTP/1.1 Connector獲得 
2) Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應 
3) Engine獲得請求localhost/yy/index.jsp,匹配它所擁有的所有虛擬主機Host 
4) Engine匹配到名爲localhost的Host(即使匹配不到也把請求交給該Host處理,因爲該Host被定義爲該Engine的默認主機) 
5) localhost Host獲得請求/yy/index.jsp,匹配它所擁有的所有Context 
6) Host匹配到路徑爲/yy的Context(如果匹配不到就把該請求交給路徑名爲”“的Context去處理) 
7) path=”/yy”的Context獲得請求/index.jsp,在它的mapping table中尋找對應的servlet 
8) Context匹配到URL PATTERN爲*.jsp的servlet,對應於JspServlet類 
9) 構造HttpServletRequest對象和HttpServletResponse對象,作爲參數調用JspServlet的doGet或doPost方法 
10)Context把執行完了之後的HttpServletResponse對象返回給Host 
11)Host把HttpServletResponse對象返回給Engine 
12)Engine把HttpServletResponse對象返回給Connector 
13)Connector把HttpServletResponse對象返回給客戶browser

Tomcat工作模式?

筆者回答:Tomcat是一個JSP/Servlet容器。其作爲Servlet容器,有三種工作模式:獨立的Servlet容器、進程內的Servlet容器和進程外的Servlet容器。

進入Tomcat的請求可以根據Tomcat的工作模式分爲如下兩類:

Tomcat作爲應用程序服務器:請求來自於前端的web服務器,這可能是Apache, IIS, Nginx等;

Tomcat作爲獨立服務器:請求來自於web瀏覽器;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章