Tomcat服務器知識整理

一、Tomcat服務器和Apache服務器的區別:轉載來源水漫金山 

 Apache與Tomcat都是Apache開源組織開發的用於處理HTTP服務的項目,兩者都是免費的,都可以做爲獨立的Web服務器運行。Apache是Web服務器而Tomcat是Java應用服務器。


Apache:是C語言實現的,專門用來提供HTTP服務。

特性:簡單、速度快、性能穩定、可配置(代理)

1、主要用於解析靜態文本,併發性能高,側重於HTTP服務;

2、支持靜態頁(HTML),不支持動態請求如:CGI、Servlet/JSP、PHP、ASP等;

3、具有很強的可擴展性,可以通過插件支持PHP,還可以單向Apache連接Tomcat實現連通;

4、Apache是世界使用排名第一的Web服務器。


Tomcat:是Java開發的一個符合JavaEE的Servlet規範的JSP服務器(Servlet容器), Apache 的擴展

特性:免費的Java應用服務器

1、主要用於解析JSP/Servlet,側重於Servlet引擎;

2、支持靜態頁,但效率沒有Apache高;支持Servlet、JSP請求;

3、Tomcat本身也內置了一個HTTP服務器用於支持靜態內容,可以通過Tomcat的配置管理工具實現與Apache整合。


Apache + Tomcat

兩者整合後優點:

如果請求網頁是靜態網頁則由Apache處理,並將結果返回;如果是動態請求,Apache會將解析工作轉發給Tomcat處理,Tomcat處理後將結果通過Apache返回。這樣可以達到分工合作,實現負載遠衡,提高系統的性能。


Apache和tomcat的關係:

打個比方:Apache是一輛卡車,上面可以裝一些東西如html等。但是不能裝水(JSP),要裝水必須要有容器(桶),Tomcat就是一個桶(裝像JSP這樣的水),而這個桶也可以不放在卡車上。

 

Tomcat與apache集成:    

  雖然tomcat也可以作web服務器,但其處理靜態html的速度比不上apache,且其作爲web服務器的功能遠不如apache,因此我們想把apache和tomcat集成起來。   
  我們以linux系統爲例介紹.   
  從apache網站下載apache1.3.22源代碼版本,然後使用如下命令配置安裝apache:  
  mkdir   /usr/local/apache    
  tar   zxvf   apache.1.32.tar.gz    
  cd   apache.1.32    
  ./configure   --prefix=/usr/local/apache   --enable-module=so   
  make    
  make   install    

  注意configure命令指定目標安裝目錄,並且加入DSO(Dynamic   Shared   Object)支持,注意一定不要忘了這一個選項。    
   
  然後下載webapp模塊,將解壓後mod_webapp.so文件放入apache的libexec目錄,編輯apache的conf目錄下的httpd.conf,在這個文件的最後加入下面三行:      
  LoadModule   webapp_module   libexec/mod_webapp.so   
  WebAppConnection   warpConnection   warp   localhost:8008   
  WebAppDeploy   examples   warpConnection   /examples/    
  第一行是加入webapp模塊,如果編譯apache時不增加DSO支持,則無法使用LoadModule指令,第二行指定tomcat與apache的連接,第三行指定部署那個應用,這兩個指令使用格式如下:   
  WebAppConnection   [connection   name]   [provider]  [host:port]    
  WebAppDeploy   [application   name]   [connection  name]   [url   path]       
  其中connection   name指定連接名,provider只能是warp,port端口與你的tomcat的配置文件server.xml最後幾行指定的要保持一致。文件如下:      
  port="8008"   minProcessors="5"  maxProcessors="75"    
  enableLookups="true"    
  acceptCount="10"   debug="0"/>    
  ******       
  application   name與你在tomcat中部署的應用名一致,url   path指定訪問這個應用的url。例如上面的例子可以通過http://localhost/examples/來訪問tomcat中的examples應用。   



二、Tomcat工作原理詳解(轉載來源:點擊打開鏈接)

tomcat目錄:

|---bin Tomcat:存放啓動和關閉tomcat腳本;

|---confTomcat:存放不同的配置文件(server.xml和web.xml);

|---doc:存放Tomcat文檔;

|---lib/japser/common:存放Tomcat運行需要的庫文件(JARS);

|---logs:存放Tomcat執行時的LOG文件;

|---src:存放Tomcat的源代碼;

|---webapps:Tomcat的主要Web發佈目錄(包括應用程序示例);

|---work:存放jsp編譯後產生的class文件

Tomcat Server的組成部分

1.1 - Server

A Server element represents the entire Catalina servletcontainer. (Singleton)

1.2 - Service

A Service element represents the combination of one ormore Connector components that share a single Engine
Service是這樣一個集合:它由一個或者多個Connector組成,以及一個Engine,負責處理所有Connector所獲得的客戶請求

1.3 - Connector

一個Connector將在某個指定端口上偵聽客戶請求,並將獲得的請求交給Engine來處理,從Engine處獲得迴應並返回客戶
TOMCAT有兩個典型的Connector,一個直接偵聽來自browser的http請求,一個偵聽來自其它WebServer的請求
Coyote Http/1.1 Connector 在端口8080處偵聽來自客戶browser的http請求
Coyote JK2 Connector 在端口8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請求

1.4 - Engine

The Engine element represents the entire requestprocessing machinery associated with a particular Service
It receives and processes all requests from one or more Connectors
and returns the completed response to the Connector for ultimate transmissionback to the client
Engine下可以配置多個虛擬主機Virtual Host,每個虛擬主機都有一個域名
當Engine獲得一個請求時,它把該請求匹配到某個Host上,然後把該請求交給該Host來處理
Engine有一個默認虛擬主機,當請求無法匹配到任何一個Host上的時候,將交給該默認Host來處理

1.5 - Host

代表一個VirtualHost,虛擬主機,每個虛擬主機和某個網絡域名Domain Name相匹配
每個虛擬主機下都可以部署(deploy)一個或者多個WebApp,每個Web App對應於一個Context,有一個Context path
當Host獲得一個請求時,將把該請求匹配到某個Context上,然後把該請求交給該Context來處理
匹配的方法是“最長匹配”,所以一個path==""的Context將成爲該Host的默認Context
所有無法和其它Context的路徑名匹配的請求都將最終和該默認Context匹配

1.6 - Context

一個Context對應於一個Web Application,一個WebApplication由一個或者多個Servlet組成
Context在創建的時候將根據配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml載入Servlet類
當Context獲得請求時,將在自己的映射表(mappingtable)中尋找相匹配的Servlet類
如果找到,則執行該類,獲得請求的迴應,並返回

2 - Tomcat Server的結構圖

3 - 配置文件$CATALINA_HOME/conf/server.xml的說明

該文件描述瞭如何啓動TomcatServer
<!----------------------------------------------------------------------------------------------->
<web-app>
     <!-- 概述:
          該文件是所有的WEBAPP共用的部署配置文件,
          每當一個WEBAPP被DEPLOY,該文件都將先被處理,然後纔是WEBAPP自己的/WEB-INF/web.xml
         -->     <!--    +-------------------------+     -->
     <!--    |       servlet類定義部分      |     -->
     <!--    +-------------------------+    -->     <!-- DefaultServlet
          當用戶的HTTP請求無法匹配任何一個servlet的時候,該servlet被執行
          URL PATTERN MAPPING : /
         -->       <servlet>
          <servlet-name>default</servlet-name>
          <servlet-class>
            org.apache.catalina.servlets.DefaultServlet
          </servlet-class>
           <init-param>
              <param-name>debug</param-name>
              <param-value>0</param-value>
          </init-param>
           <init-param>
              <param-name>listings</param-name>
              <param-value>true</param-value>
           </init-param>
          <load-on-startup>1</load-on-startup>
       </servlet>
     <!-- InvokerServlet
          處理一個WEBAPP中的匿名servlet
          當一個servlet被編寫並編譯放入/WEB-INF/classes/中,卻沒有在/WEB-INF/web.xml中定義的時候
          該servlet被調用,把匿名servlet映射成/servlet/ClassName的形式
          URL PATTERN MAPPING :/servlet/*
         -->       <servlet>
          <servlet-name>invoker</servlet-name>
          <servlet-class>
            org.apache.catalina.servlets.InvokerServlet
          </servlet-class>
           <init-param>
              <param-name>debug</param-name>
              <param-value>0</param-value>
           </init-param>
          <load-on-startup>2</load-on-startup>
       </servlet>
     <!-- JspServlet
          當請求的是一個JSP頁面的時候(*.jsp)該servlet被調用
          它是一個JSP編譯器,將請求的JSP頁面編譯成爲servlet再執行
          URL PATTERN MAPPING :*.jsp
         -->       <servlet>
          <servlet-name>jsp</servlet-name>
          <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
           <init-param>
              <param-name>logVerbosityLevel</param-name>
              <param-value>WARNING</param-value>
          </init-param>
          <load-on-startup>3</load-on-startup>
       </servlet>    <!--     +---------------------------+    -->
     <!--    |       servlet映射定義部分      |     -->
     <!--    +---------------------------+     -->   
       <servlet-mapping>
          <servlet-name>default</servlet-name>
          <url-pattern>/</url-pattern>
      </servlet-mapping>      <servlet-mapping>
           <servlet-name>invoker</servlet-name>
          <url-pattern>/servlet/*</url-pattern>
      </servlet-mapping>      <servlet-mapping>
          <servlet-name>jsp</servlet-name>
          <url-pattern>*.jsp</url-pattern>
       </servlet-mapping>
     <!--    +------------------------+     -->
     <!--    |       其它部分,略去先      |     -->
     <!--    +------------------------+    -->       ... ... ......</web-app><!-- 啓動Server
        在端口8005處等待關閉命令
        如果接受到"SHUTDOWN"字符串則關閉服務器
        --><Serverport="8005" shutdown="SHUTDOWN" debug="0">
     <!-- Listener ???
          目前沒有看到這裏
         -->     <ListenerclassName="org.apache.catalina.mbeans.ServerLifecycleListener"debug="0"/>
     <ListenerclassName="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"debug="0"/>
     <!-- Global JNDI resources ???
          目前沒有看到這裏,先略去
         -->     <GlobalNamingResources>
       ... ... ... ...
     </GlobalNamingResources>
     <!-- Tomcat的StandaloneService
          Service是一組Connector的集合
          它們共用一個Engine來處理所有Connector收到的請求
         -->     <Servicename="Tomcat-Standalone">
       <!-- Coyote HTTP/1.1 Connector
            className : 該Connector的實現類是org.apache.coyote.tomcat4.CoyoteConnector
            port : 在端口號8080處偵聽來自客戶browser的HTTP1.1請求
           minProcessors : 該Connector先創建5個線程等待客戶請求,每個請求由一個線程負責
           maxProcessors : 當現有的線程不夠服務客戶請求時,若線程總數不足75個,則創建新線程來處理請求
            acceptCount: 當現有線程已經達到最大數75時,爲客戶請求排隊
                         當隊列中請求數超過100時,後來的請求返回Connectionrefused錯誤
            redirectport: 當客戶請求是https時,把該請求轉發到端口8443去
            其它屬性略
           -->       <ConnectorclassName="org.apache.coyote.tomcat4.CoyoteConnector"
                 port="8080"
                 minProcessors="5" maxProcessors="75"acceptCount="100"
                 enableLookups="true"
                 redirectPort="8443"
                 debug="0"
                 connectionTimeout="20000"
                 useURIValidationHack="false"
                 disableUploadTimeout="true" />
       <!-- Engine用來處理Connector收到的Http請求
            它將匹配請求和自己的虛擬主機,並把請求轉交給對應的Host來處理
            默認虛擬主機是localhost
           -->       <Enginename="Standalone" defaultHost="localhost"debug="0">
            <!-- 日誌類,目前沒有看到,略去先-->         <LoggerclassName="org.apache.catalina.logger.FileLogger".../>         <!-- Realm,目前沒有看到,略去先-->         <RealmclassName="org.apache.catalina.realm.UserDatabaseRealm" .../>
         <!-- 虛擬主機localhost
             appBase : 該虛擬主機的根目錄是webapps/
              它將匹配請求和自己的Context的路徑,並把請求轉交給對應的Context來處理
             -->         <Host name="localhost"debug="0" appBase="webapps" unpackWARs="true"autoDeploy="true">
               <!-- 日誌類,目前沒有看到,略去先-->           <LoggerclassName="org.apache.catalina.logger.FileLogger" .../>
               <!-- Context,對應於一個Web App
               path : 該Context的路徑名是"",故該Context是該Host的默認Context
               docBase : 該Context的根目錄是webapps/mycontext/
               -->           <Contextpath="" docBase="mycontext" debug="0"/>
                 <!-- 另外一個Context,路徑名是/wsota-->           <Contextpath="/wsota" docBase="wsotaProject"debug="0"/>  </Host>      </Engine></Service></Server>

4 - Context的部署配置文件web.xml的說明

一個Context對應於一個Web App,每個Web App是由一個或者多個servlet組成的
當一個Web App被初始化的時候,它將用自己的ClassLoader對象載入“部署配置文件web.xml”中定義的每個servlet類
它首先載入在$CATALINA_HOME/conf/web.xml中部署的servlet類
然後載入在自己的Web App根目錄下的WEB-INF/web.xml中部署的servlet類
web.xml文件有兩部分:servlet類定義和servlet映射定義
每個被載入的servlet類都有一個名字,且被填入該Context的映射表(mapping table)中,和某種URL PATTERN對應
當該Context獲得請求時,將查詢mapping table,找到被請求的servlet,並執行以獲得請求迴應

分析一下所有的Context共享的web.xml文件,在其中定義的servlet被所有的Web App載入

5 - Tomcat Server處理一個http請求的過程

假設來自客戶的請求爲:
http://localhost:8080/wsota/wsota_index.jsp

1) 請求被髮送到本機端口8080,被在那裏偵聽的Coyote HTTP/1.1 Connector獲得
2) Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應
3) Engine獲得請求localhost/wsota/wsota_index.jsp,匹配它所擁有的所有虛擬主機Host
4) Engine匹配到名爲localhost的Host(即使匹配不到也把請求交給該Host處理,因爲該Host被定義爲該Engine的默認主機)
5) localhost Host獲得請求/wsota/wsota_index.jsp,匹配它所擁有的所有Context
6) Host匹配到路徑爲/wsota的Context(如果匹配不到就把該請求交給路徑名爲""的Context去處理)
7) path="/wsota"的Context獲得請求/wsota_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啓動腳本分析

1. startup.bat腳本解析下面我們首先來看看startup.bat腳本是如何啓動Tomcat的。Startup腳本非常明瞭,它的主要任務就是先設置CATALINA_HOME的環境變量,讓該環境變量指向Tomcat的安裝目錄;然後在安裝目錄的bin子目錄下找catalina.bat文件,如果找不到,就打印出錯誤信息並退出,如果在bin目錄下找到catalina.bat文件,就準備執行該文件。不過,在執行該文件之前,startup腳本還做了一件工作,那就是尋找參數。startup腳本可以帶多個參數,在Java主類中,第一個參數爲args[0],而在MS-DOS腳本中,第一個參數可以通過”%1”得到,如果您想要得到DOS腳本中得到第二個參數,調用”%2”。但是,在腳本參數數目未知的情況下,我們就只能通過goto循環調用shift命令來獲得腳本的所有參數,下面這個簡單的實驗腳本有助於我們理解如何使用shift命令。 @echo off 

echo Print parameters by %%1 andshift loop
:loopStart
if""%1""=="""" goto loopEnd
echo Paramter is %1
shift
goto loopStart
:loopEnd
如果把上面的腳本保存成test.bat並在DOS中執行該腳本,執行結果如下。
下面就是Startup.bat腳本的詳細註釋,如果想要在DOS腳本中註釋一行,前面加上rem即可,這相當於Java的雙斜槓(//)註釋,下面程序中,凡是以REM開頭然後接着中文的行,都是筆者加上的註釋,以幫助讀者理解該腳本。@echo off
if "%OS%" == "Windows_NT" setlocal
rem ---------------------------------------------------------------------------
rem Start script for the CATALINA Server
rem
rem $Id: startup.bat,v 1.6 2004/05/27 18:25:11 yoavs Exp $
rem ---------------------------------------------------------------------------rem 首先定義一個變量CURRENT_DIR,然後把當前目錄作爲一個字符串賦給它
rem Guess CATALINA_HOME if not defined
set CURRENT_DIR=%cd% rem 如果CATALINA_HOME變量已經賦值,程序轉到gotHome行繼續
if not "%CATALINA_HOME%" == "" goto gotHome rem 把當前目錄的值作爲字符串賦給CATALINA_HOME變量
set CATALINA_HOME=%CURRENT_DIR% rem 如果當前目錄的bin子目錄下發現catalina.bat文件,程序轉到okHome行繼續
rem 否則執行下一行“cd..”。
Rem 因爲缺省情況下當前目錄就是bin目錄,所以缺省情況下程序不轉入okHome行
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome rem 回上層目錄
cd .. rem 把當前目錄的上層目錄作爲字符串賦給再次CATALINA_HOME變量,覆蓋第一次的賦值
set CATALINA_HOME=%cd% rem 重新回到當前目錄
cd %CURRENT_DIR% :gotHome rem 如果在當前目錄的父目錄的bin子文件夾下發現catalina.bat文件,程序轉到okHome行繼續
rem 否則程序打印兩行錯誤信息,然後退出
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome rem 設置一個變量,存儲catalina.bat的完整路徑
set EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat rem 再次檢查catalina.bat是否存在,如果不存在,打印兩行錯誤信息,退出
rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find %EXECUTABLE%
echo This file is needed to run this program
goto end
:okExec rem 檢查腳本是否帶參數,如果發現參數,把第一個參數賦值給 CMD_LINE_ARGS變量
rem 如果腳本帶有多個參數,程序設置了一個循環setArgs,
rem 不斷把所帶的參數加到CMD_LINE_ARGS變量中
rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs rem 執行catalina.bat腳本,該腳本的第一個參數爲start,後面的參數是從本腳本中傳入的
call "%EXECUTABLE%" start %CMD_LINE_ARGS% :end 那麼讀者也許要問,問什麼要通過startup腳本來調用catalina腳本,直接一個腳本不更方便嗎?細心的讀者或許會發現,在缺省情況下,startup腳本只能放在兩個位置,一是Tomcat的安裝目錄,一個就是Tomcat安裝目錄的bin子目錄。這是什麼意思呢?如果Tomcat安裝目錄是C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28,那麼startup腳本只能放在C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28\目錄或者C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28\bin目錄下才能運行,如果拷貝startup文件到其它目錄,我們就會看到下面的錯誤(以Tomcat運行在C:\carl目錄下爲例): C:\carl>startup
CATALINA_HOME C:\
The CATALINA_HOME environment variable is not defined correctly
This environment variable is needed to run this program
那麼,如果我們想讓Tomcat在桌面上能成功啓動,那麼該怎麼辦呢?當然,我們首先想到的是爲startup創建一個快捷方式,然後拷貝該快捷方式到桌面,這是一種辦法。另一種辦法就是修改startup.bat文件,在startup.bat腳本的第八行處添上一句腳本,讓 CATALINA_HOME變量指向用戶Tomcat的安裝路徑,這樣,startup.bat就可以拷貝到機器的任何目錄執行。這個startup.bat腳本就是提供給使用者用來修改的,我們可以在其中設置JAVA_HOME,CATALINA_HOME等環境變量,但我們並不需要深入到較爲複雜的catalina.bat腳本中,這正是startup.bat腳本的真正用意所在。我們知道,軟件設計模式中有一個重要的原則就是開閉原則,即我們可以允許別人擴展我們的程序,但在程序發佈後,我們拒絕任何修改,因爲修改會產生新的Bug,使得我們已經Bug-free的程序又要重新測試。開閉原則是面向對象世界中的一個非常重要的原則,我們可以把這個原則從Java類擴展至源代碼級別。startup腳本就是要求用戶不要修改catalina.bat腳本,這是符合軟件設計思想的。我們如果想要徹底貫徹這個重要的軟件設計原則,可以寫一個新腳本tomcat.bat,腳本內容大致如下: set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09
set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28
call %CATALINA_HOME%\bin\startup.bat 這個tomcat.bat文件可以存放在任何目錄並能執行,並且不需要修改tomcat自帶的任何腳本及其它環境變量,這就徹底貫徹了開閉原則。







發佈了12 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章