生活随笔
收集整理的這篇文章主要介紹了
简单谈Tomcat的实现原理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、前言
在我們接觸java之后,相信大家都編寫過服務器程序,這個時候就需要用到Tomcat了。Tomcat 服務器是一個開源的輕量級Web應用服務器,在中小型系統和并發量小的場合下被普遍使用,是開發和調試Servlet、JSP 程序的首選。
二、Tomcat的基本原理
Tomcat的架構
Tomcat主要組件:服務器Server,服務Service,連接器Connector、容器Container。連接器Connector和容器Container是Tomcat的核心。Tomcat 還有其它重要的組件,如安全組件 security、logger 日志組件、session、mbeans、naming 等其它組件。這些組件共同為 Connector 和 Container 提供必要的服務。一個Container容器和一個或多個Connector組合在一起,加上其他一些支持的組件共同組成一個Service服務,有了Service服務便可以對外提供能力了,但是Service服務的生存需要一個環境,這個環境便是Server,Server組件為Service服務的正常使用提供了生存環境,Server組件可以同時管理一個或多個Service服務。
- Server:指的就是整個 Tomcat 服 務器,包含多組服務,負責管理和 啟動各個 Service,同時監聽 8005 端口發過來的 shutdown 命令,用 于關閉整個容器 ;
- Service:Tomcat 封裝的、對外提供完整的、基于組件的 web 服務, 包含 Connectors、Container 兩個 核心組件,以及多個功能組件,各 個 Service 之間是獨立的,但是共享 同一 JVM 的資源 ;
- Connector:Tomcat 與外部世界的連接器,監聽固定端口接收外部請求,傳遞給 Container,并 將 Container 處理的結果返回給外部;
- Container:Catalina,Servlet 容器,內部有多層容器組成,用于管理 Servlet 生命周期,調用 servlet 相關方法。
- Loader:封裝了 Java ClassLoader,用于 Container 加載類文件;
- Realm:Tomcat 中為 web 應用程序提供訪問認證和角色管理的機制;
- JMX:Java SE 中定義技術規范,是一個為應用程序、設備、系統等植入管理功能的框架,通過 JMX 可以遠程監控 Tomcat 的運行狀態;
- Jasper:Tomcat 的 Jsp 解析引擎,用于將 Jsp 轉換成 Java 文件,并編譯成 class 文件。 Session:負責管理和創建 session,以及 Session 的持久化(可自定義),支持 session 的集
群。 - Pipeline:在容器中充當管道的作用,管道中可以設置各種 valve(閥門),請求和響應在經由管道中各個閥門處理,提供了一種靈活可配置的處理請求和響應的機制。
- Naming:命名服務,JNDI, Java 命名和目錄接口,是一組在 Java 應用中訪問命名和目錄服務的 API。命名服務將名稱和對象聯系起來,使得我們可以用名稱訪問對象,目錄服務也是一種命名服務,對象不但有名稱,還有屬性。Tomcat 中可以使用 JNDI 定義數據源、配置信息,用于開發 與部署的分離。
Connector
一個Connecter將在某個指定的端口上偵聽客戶請求,接收瀏覽器的發過來的 tcp 連接請求,創建一個 Request 和 Response 對象分別用于和請求端交換數據,然后會產生一個線程來處理這個請求并把產生的 Request 和 Response 對象傳給處理Engine(Container中的一部分),從Engine出獲得響應并返回客戶。 Tomcat中有兩個經典的Connector,一個直接偵聽來自Browser的HTTP請求,另外一個來自其他的WebServer請求。HTTP/1.1 Connector在端口8080處偵聽來自客戶Browser的HTTP請求,AJP/1.3 Connector在端口8009處偵聽其他Web Server(其他的HTTP服務器)的Servlet/JSP請求。 Connector 最重要的功能就是接收連接請求然后分配線程讓 Container 來處理這個請求,所以這必然是多線程的,多線程的處理是 Connector 設計的核心。
Container容器
Container是容器的父接口,該容器的設計用的是典型的責任鏈的設計模式,它由四個自容器組件構成,分別是Engine、Host、Context、Wrapper。這四個組件是負責關系,存在包含關系。通常一個Servlet class對應一個Wrapper,如果有多個Servlet定義多個Wrapper,如果有多個Wrapper就要定義一個更高的Container,如Context。 Context 還可以定義在父容器 Host 中,一個Host可以對應多個Context,Host 不是必須的,但是要運行 war 程序,就必須要 Host,因為 war 中必有 web.xml 文件,這個文件的解析就需要 Host 了,如果要有多個 Host 就要定義一個 top 容器 Engine 了。而 Engine 沒有父容器了,一個 Engine 代表一個完整的 Servlet 引擎。
- Engine 容器比較簡單,它只定義了一些基本的關聯關系。
- Host 容器是Engine 的子容器,一個Host在 Engine 中代表一個虛擬主機,這個虛擬主機的作用就是運行多個應用,它負責安裝和展開這些應用,并且標識這個應用以便能夠區分它們。它的子容器通常是
- Context,它除了關聯子容器外,還有就是保存一個主機應該有的信息。Context 容器代表 Servlet 的 Context,它具備了 Servlet 運行的基本環境,理論上只要有 Context 就能運行 Servlet 了。簡單的 Tomcat 可以沒有 Engine 和 Host。Context 最重要的功能就是管理它里面的Servlet 實例,Servlet 實例在 Context 中是以 Wrapper 出現的,還有一點就是 Context 如何找到正確的Servlet 來執行它呢,Tomcat5 以前是通過一個 Mapper 類來管理的,Tomcat5 以后這個功能被移到了 request
中。 - Wrapper容器代表一個 Servlet,負責管理一個Servlet,包括的 Servlet 的裝載、初始化、執行以及資源回收。Wrapper是最底層的容器,它沒有子容器,所以調用它的addChild 將會報錯。Wrapper 的實現類是StandardWrapper,StandardWrapper還實現了擁有一個Servlet 初始化信息的 ServletConfig,由此看出 StandardWrapper將直接和 Servlet 的各種信息打交道。
HTTP請求過程
Tomcat Server處理一個HTTP請求的過程:
復制代碼
用戶點擊網頁內容,請求被發送到本機端口8080,被在那里監聽的Coyote HTTP/1.1 Connector獲得。Connector把該請求交給它所在的Service的Engine來處理,并等待Engine的回應。Engine獲得請求localhost/test/index.jsp,匹配所有的虛擬主機Host。Engine匹配到名為localhost的Host(即使匹配不到也把請求交給該Host處理,因為該Host被定義為該Engine的默認主機),名為localhost的Host獲得請求/test/index.jsp,匹配它所擁有的所有的Context。Host匹配到路徑為/test的Context(如果匹配不到就把該請求交給路徑名為“”的Context去處理)。path=“/test”的Context獲得請求/index.jsp,在它的mapping
table中尋找出對應的Servlet。Context匹配到URL PATTERN為*.jsp的Servlet,對應于Jsp的Servlet類。構造HttpServletRequest對象和HttpServletResponse對象,作為參數調用Servlet的doGet()或doPost(),執行業務邏輯、數據存儲等程序。Context把執行完之后的HttpServletResponse對象返回給Host。Host把HttpServletResponse對象返回給Engine。Engine把HttpServletResponse對象返回Connector。Connector把HttpServletResponse對象返回給客戶Browser。
server.xml配置
下面看一個server.xml配置實例:
1 規劃:
2 網站網頁目錄:
/web
/www 域名:www
.test1
.com
3 論壇網頁目錄:
/web
/bbs URL:bbs
.test1
.com
/bbs
4 網站管理程序:$CATALINA_HOME
/wabapps URL:manager
.test
.com 允許訪問地址:
172.23.136.*
5 6 conf
/server
.xml
7 <Server port
="8005" shutdown
="SHUTDOWN"> 8 <Listener className
="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> 9 <Listener className
="org.apache.catalina.core.JasperListener" />
10 <Listener className
="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
11 <Listener className
="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
12 <Listener className
="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
13 <GlobalNamingResources>
14 <!-- 全局命名資源,來定義一些外部訪問資源,其作用是為所有引擎應用程序所引用的外部資源的定義
--!>
15 <Resource name
="UserDatabase" auth
="Container"
16 type
="org.apache.catalina.UserDatabase"
17 description
="User database that can be updated and saved"
18 factory
="org.apache.catalina.users.MemoryUserDatabaseFactory"
19 pathname
="conf/tomcat-users.xml" />
20 </GlobalNamingResources>
21 <!-- 定義的一個名叫“
UserDatabase”的認證資源,將conf
/tomcat
-users
.xml加載至內存中,在需要認證的時候到內存中進行認證
-->
22 <Service name
="Catalina">
23 <!-- # 定義
Service組件,同來關聯
Connector和
Engine,一個
Engine可以對應多個
Connector,每個
Service中只能一個
Engine --!>
24 <Connector port
="80" protocol
="HTTP/1.1" connectionTimeout
="20000" redirectPort
="8443" />
25 <!-- 修改HTTP
/1.1的
Connector監聽端口為
80.客戶端通過瀏覽器訪問的請求,只能通過HTTP傳遞給tomcat。
-->
26 <Connector port
="8009" protocol
="AJP/1.3" redirectPort
="8443" />
27 <Engine name
="Catalina" defaultHost
="test.com">
28 <!-- 修改當前
Engine,默認主機是,www
.test
.com
-->
29 <Realm className
="org.apache.catalina.realm.LockOutRealm">
30 <Realm className
="org.apache.catalina.realm.UserDatabaseRealm"
31 resourceName
="UserDatabase"/>
32 </Realm>
33 #
Realm組件,定義對當前容器內的應用程序訪問的認證,通過外部資源
UserDatabase進行認證
34 <Host name
="test.com" appBase
="/web" unpackWARs
="true" autoDeploy
="true">
35 <!-- 定義一個主機,域名為:test
.com,應用程序的目錄是
/web,設置自動部署,自動解壓
-->
36 <Alias>www
.test
.com
</Alias>
37 <!-- 定義一個別名www
.test
.com,類似apache的
ServerAlias -->
38 <Context path
="" docBase
="www/" reloadable
="true" />
39 <!-- 定義該應用程序,訪問路徑
"",即訪問www
.test
.com即可訪問,網頁目錄為:相對于appBase下的www
/,即
/web
/www,并且當該應用程序下web
.xml或者類等有相關變化時,自動重載當前配置,即不用重啟tomcat使部署的新應用程序生效
-->
40 <Context path
="/bbs" docBase
="/web/bbs" reloadable
="true" />
41 <!-- 定義另外一個獨立的應用程序,訪問路徑為:www
.test
.com
/bbs,該應用程序網頁目錄為
/web
/bbs
-->
42 <Valve className
="org.apache.catalina.valves.AccessLogValve" directory
="/web/www/logs"
43 prefix
="www_access." suffix
=".log"
44 pattern
="%h %l %u %t "%r
" %s %b" />
45 <!-- 定義一個
Valve組件,用來記錄tomcat的訪問日志,日志存放目錄為:
/web
/www
/logs如果定義為相對路徑則是相當于$CATALINA_HOME,并非相對于appBase,這個要注意。定義日志文件前綴為www_access
.并以
.log結尾,pattern定義日志內容格式,具體字段表示可以查看tomcat官方文檔
-->
46 </Host>
47 <Host name
="manager.test.com" appBase
="webapps" unpackWARs
="true" autoDeploy
="true">
48 <!-- 定義一個主機名為man
.test
.com,應用程序目錄是$CATALINA_HOME
/webapps
,自動解壓,自動部署
-->
49 <Valve className
="org.apache.catalina.valves.RemoteAddrValve" allow
="172.23.136.*" />
50 <!-- 定義遠程地址訪問策略,僅允許
172.23.136.*網段訪問該主機,其他的將被拒絕訪問
-->
51 <Valve className
="org.apache.catalina.valves.AccessLogValve" directory
="/web/bbs/logs"
52 prefix
="bbs_access." suffix
=".log"
53 pattern
="%h %l %u %t "%r
" %s %b" />
54 <!-- 定義該主機的訪問日志
-->
55 </Host>
56 </Engine>
57 </Service>
58 </Server>
59
60 conf
/tomcat
-users
.xml
61 <?xml version
='1.0' encoding
='utf-8'?>
62 <tomcat
-users
>
63 <role rolename
="manager-gui" />
64 <!-- 定義一種角色名為:manager
-gui
-->
65 <user username
="cz" password
="manager$!!110" roles
="manager-gui" />
66 <!-- 定義一個用戶的用戶名以及密碼,并賦予manager
-gui的角色
-->
67 </tomcat
-users
>
Tomcat 日志概述
日志分為兩種,系統日志和控制臺日志。
系統日志主要包含運行中日志和訪問日志,分為5類:catalina、localhost、manager、localhost_access、host-manager,在logging.properties文件中進行配置。控制臺日志包含了catalina日志,另外包含了程序輸出的日志(System打印,Console),可以將其日志配置輸出到文件catalina.out中。
日志級別分為如下 7 種:
SEVERE
(highestvalue
) > WARNING
> INFO
> CONFIG
> FINE
> FINER
> FINEST
(lowest value
)
系統日志:
catalina日志 :Catalina引擎的日志文件,文件名catalina.日期.loglocalhost日志:Tomcat下內部代碼拋出異常的日志,文件名localhost.日期.loglocalhost_access : 默認 tomcat 不記錄訪問日志,server.xml文件中配置Valve可以使tomcat 記錄訪問日志manager、host-manager :Tomcat下默認manager應用日志
控制臺日志:
在Linux系統中,Tomcat 啟動后默認將很多信息都寫入到 catalina.out 文件中,我們可以通過tail -f catalina.out 來跟蹤Tomcat 和相關應用運行的情況。在windows下,我們使用startup.bat啟動Tomcat以后,會發現catalina日志與Linux記錄的內容有很大區別,大多信息只輸出到屏幕而沒有記錄到catalina.out里面。,可以通過設置來做到這一點。
文章轉自
總結
以上是生活随笔為你收集整理的简单谈Tomcat的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。