一.背景
最近找工作,被別人問到了tomcat的最大連接數是多少,沒有回答上來,作爲一個java開發者,天天都會用到tomcat,卻對tomcat所知甚少,這個就很不應該了,這篇博客其實沒有多少自己的理解都是照着其他博客搬運過來的,只是記錄一下自己的學習過程,也是自己學習tomcat的一個總結。
二.tomcat根目錄介紹
【bin】目錄主要是用來存放tomcat的命令,主要有兩大類,一類是以.sh結尾的(linux命令),另一類是以.bat結尾的(windows命令)。
很多環境變量的設置都在此處,例如可以設置JDK路徑、TOMCAT路徑
startup 用來啓動tomcat
shutdown 用來關閉tomcat
修改catalina可以設置tomcat的內存
【conf】目錄主要是用來存放tomcat的一些配置文件。
- server.xml可以設置端口號、設置域名或IP、默認加載的項目、請求編碼
- web.xml可以設置tomcat支持的文件類型
- context.xml可以用來配置數據源之類的
- tomcat-users.xml用來配置管理tomcat的用戶與權限
- 在Catalina目錄下可以設置默認加載的項目
【lib】目錄主要用來存放tomcat運行需要加載的jar包。
例如,像連接數據庫的jdbc的包我們可以加入到lib目錄中來。
【logs】目錄用來存放tomcat在運行過程中產生的日誌文件,非常重要的是在控制檯輸出的日誌。(清空不會對tomcat運行帶來影響)
在windows環境中,控制檯的輸出日誌在catalina.xxxx-xx-xx.log文件中
在linux環境中,控制檯的輸出日誌在catalina.out文件中
【temp】目錄用戶存放tomcat在運行過程中產生的臨時文件。(清空不會對tomcat運行帶來影響)
【webapps】目錄用來存放應用程序
當tomcat啓動時會去加載webapps目錄下的應用程序。可以以文件夾、war包、jar包的形式發佈應用。
當然,你也可以把應用程序放置在磁盤的任意位置,在配置文件中映射好就行。
【work】目錄用來存放tomcat在運行時的編譯後文件,例如JSP編譯後的文件。
清空work目錄,然後重啓tomcat,可以達到清除緩存的作用。
三.請求在tomcat中的處理流程
上圖的具體流程如下
1.用戶在瀏覽器上輸入地址,發送http請求,被端口號爲8080,協議是http的Connector捕獲。
2.Connector將請求傳遞給自己所屬service的容器,就是tomcat中Engine(引擎)
3.Engine再將請求根據配置的虛擬主機的name來確定對應的虛擬主機,如果沒有匹配的虛擬主機,則使用默認的虛擬主機
4.Host容器然後再根據context中配置的path來確定具體web應用
5.Context獲得請求/index.jsp,在它的mapping table中尋找出對應的Servlet,Context匹配到URL 爲*.jsp的Servlet,對應JspServlet類。
6.將HttpServletRequest,HttpServletResponse作爲參數來調用doGet()或者doPost()方法,執行業務邏輯,或者數據存取
7.將程序調用結果放在HttpServletResponse對象中,將HttpServletResponse傳遞給context所屬於的虛擬主機
8.Host虛擬主機將HttpServletResponse對象傳遞給Engine
9.Engine把HttpServletResponse對象返回Connector。
10.Connector把HttpServletResponse對象返回給客戶Browser。
四.各常見組件:
1、服務器(server):Tomcat的一個實例,通常一個JVM只能包含一個Tomcat實例;因此,一臺物理服務器上可以在啓動多個JVM的情況下在每一個JVM中啓動一個Tomcat實例,每個實例分屬於一個獨立的管理端口。這是一個頂級組件。
2、服務(service):一個服務組件通常包含一個引擎和與此引擎相關聯的一個或多個連接器。給服務命名可以方便管理員在日誌文件中識別不同服務產生的日誌。一個server可以包含多個service組件,但通常情下只爲一個service指派一個server。
連接器類組件:
3、連接器(connectors):負責連接客戶端(可以是瀏覽器或Web服務器)請求至Servlet容器內的Web應用程序,通常指的是接收客戶發來請求的位置及服務器端分配的端口。默認端口通常是HTTP協議的8080,管理員也可以根據自己的需要改變此端口。一個引擎可以配置多個連接器,但這些連接器必須使用不同的端口。默認的連接器是基於HTTP/1.1的Coyote。同時,Tomcat也支持AJP、JServ和JK2連接器。
容器類組件:
4、引擎(Engine):引擎通是指處理請求的Servlet引擎組件,即Catalina Servlet引擎,它檢查每一個請求的HTTP首部信息以辨別此請求應該發往哪個host或context,並將請求處理後的結果返回的相應的客戶端。嚴格意義上來說,容器不必非得通過引擎來實現,它也可以是隻是一個容器。如果Tomcat被配置成爲獨立服務器,默認引擎就是已經定義好的引擎。而如果Tomcat被配置爲Apache Web服務器的提供Servlet功能的後端,默認引擎將被忽略,因爲Web服務器自身就能確定將用戶請求發往何處。一個引擎可以包含多個host組件。
5、主機(Host):主機組件類似於Apache中的虛擬主機,但在Tomcat中只支持基於FQDN的“虛擬主機”。一個引擎至少要包含一個主機組件。
6、上下文(Context):Context組件是最內層次的組件,它表示Web應用程序本身。配置一個Context最主要的是指定Web應用程序的根目錄,以便Servlet容器能夠將用戶請求發往正確的位置。Context組件也可包含自定義的錯誤頁,以實現在用戶訪問發生錯誤時提供友好的提示信息。
五.server.xml配置文件詳解
<Server port="8005" shutdown="SHUTDOWN">
<!-- 屬性說明
port:指定一個端口,這個端口負責監聽關閉Tomcat的請求
shutdown:向以上端口發送的關閉服務器的命令字符串
-->
<Listener className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
<GlobalNamingResources>
<Environment name="simpleValue" type="java.lang.Integer" value="30"/>
<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元素只能有一個Engine元素.元素處理在同一個<Service>中所有<Connector>元素接收到的客戶請求
-->
<Service name="Catalina">
<!-- 屬性說明
name:Service的名稱
-->
<!--
Connector元素:
由Connector接口定義.<Connector>元素代表與客戶程序實際交互的組件,它負責接收客戶請求,以及向客戶返回響應結果.
-->
<Connector port="80" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
<!-- 屬性說明
port:服務器連接器的端口號,該連接器將在指定端口偵聽來自客戶端的請求。
enableLookups:如果爲true,則可以通過調用request.getRemoteHost()進行DNS查詢來得到遠程客戶端的實際主機名;
若爲false則不進行DNS查詢,而是返回其ip地址。
redirectPort:表示當強制要求https而請求是http時,重定向至端口號爲8443的Connecto
acceptCount:當所有可以使用的處理請求的線程都被用光時,可以放到處理隊列中的請求數,超過這個數的請求將不予處理,而返回Connection refused錯誤。
connectionTimeout:等待超時的時間數(以毫秒爲單位)。
maxThreads:設定在監聽端口的線程的最大數目,這個值也決定了服務器可以同時響應客戶請求的最大數目.默認值爲200。
protocol:必須設定爲AJP/1.3協議。
address:如果服務器有兩個以上IP地址,該屬性可以設定端口監聽的IP地址,默認情況下,端口會監聽服務器上所有IP地址。
minProcessors:服務器啓動時創建的處理請求的線程數,每個請求由一個線程負責。
maxProcessors:最多可以創建的處理請求的線程數。
minSpareThreads:最小備用線程 。
maxSpareThreads:最大備用線程。
debug:日誌等級。
disableUploadTimeout:禁用上傳超時,主要用於大數據上傳時。
-->
<Connector port="8009"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
<!-- 負責和其他HTTP服務器建立連接。在把Tomcat與其他HTTP服務器集成時就需要用到這個連接器。 -->
<Engine name="Catalina" defaultHost="localhost">
<!-- 屬性說明
name:對應$CATALINA_HOME/config/Catalina中的Catalina
defaultHost:對應Host元素中的name屬性,也就是和$CATALINA_HOME/config/Catalina/localhost中的localhost
缺省的處理請求的虛擬主機名,它至少與其中的一個Host元素的name屬性值是一樣的
debug:日誌等級
-->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
<!--
由Host接口定義.一個Engine元素可以包含多個<Host>元素.
每個<Host>的元素定義了一個虛擬主機.它包含了一個或多個Web應用.
-->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<!-- 屬性說明
name:在此例中一直被強調爲$CATALINA_HOME/config/Catalina/localhost中的localhost虛擬主機名
debug:是日誌的調試等級
appBase:默認的應用路徑,也就是把應用放在一個目錄下,並在autoDeploy爲true的情況下,可自動部署應用此路徑相對於$CATALINA_HOME/ (web applications的基本目錄)
unpackWARs:設置爲true,在Web應用爲*.war是,解壓此WAR文件.
如果爲true,則tomcat會自動將WAR文件解壓;否則不解壓,直接從WAR文件中運行應用程序.
autoDeploy:默認爲true,表示如果有新的WEB應用放入appBase 並且Tomcat在運行的情況下,自動載入應用
-->
<Context path="/demm" docBase="E:\\projects\\demm\\WebRoot" debug="0" reloadable="true" >
</Context>
<!-- 屬性說明
path:訪問的URI,如:http://localhost/是我的應用的根目錄,訪問此應用將用:http://localhost/demm進行操作,此元素必須,
表示此web application的URL的前綴,用來匹配一個Context。請求的URL形式爲http://localhost:8080/path/*
docBase:WEB應用的目錄,此目錄必須符合Java WEB應用的規範,web application的文件存放路徑或者是WAR文件存放路徑。
debug:日誌等級
reloadable:是否在程序有改動時重新載入,設置成true會影響性能,但可自動載入修改後的文件,
如果爲true,則Tomcat將支持熱部署,會自動檢測web application的/WEB-INF/lib和/WEB-INF/classes目錄的變化,
自動裝載新的JSP和Servlet,我們可以在不重起Tomcat的情況下改變web application
-->
</Host>
</Engine>
</Service>
</Server>
tomcat最大的連接數是maxConnections+acceptCount之和,當工作線程達到maxThreads後,後面的請求過來先到acceptCount這個隊列中,然後再被轉移到maxConnections這個隊列中,當maxConnections這個隊列滿了後,acceptCount這個隊列可以繼續接受請求,當acceptCount隊列達到最大值的時候,就拒絕請求了。其中maxConnections默認的值是10000,acceptCount默認值是100,maxThreads默認值是200。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<!-- DispatcherServlet初始化的上下文加載的Bean是隻對Spring Web MVC有效的Bean,如Controller、HandlerMapping、HandlerAdapter等等,該初始化上下文應該只加載Web相關組件。 -->
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springController.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--
ContextLoaderListener初始化的上下文加載的Bean是對於整個應用程序共享的,不管是使用什麼表現層技術,一般如DAO層、Service層Bean;
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springController.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
上面是一個web工程的web.xml配置文件,當請求進入到context裏面的時候,context會找到doBase下面的web工程的web.xml配置文件,然後去尋找servlet-mapping中的url-pattern相匹配,如果匹配上了,就會尋找相應的servlet執行請求,上面的servlet就是DispatcherServlet。