Tomcat最主要的功能是提供Servlet/JSP容器,儘管它也可以作為獨立的Java Web伺服器,它在對靜態資源(如HTML檔案或影像檔)的處理速度,以及提供的Web伺服器管理功能方面都不如其他專業的HTTP伺服器,如IIS和Apache伺服器。
因此在實際應用中,常常把Tomcat與其他HTTP伺服器整合。對於不支援Servlet/JSP的HTTP伺服器,可以通過Tomcat伺服器來運行Servlet/JSP組件。
當Tomcat與其他HTTP伺服器整合時,Tomcat伺服器的工作模式通常為進程外的Servlet容器,Tomcat伺服器與其他HTTP伺服器之間通過專門的外掛程式來通訊。關於Tomcat伺服器的工作模式的概念可以參考本書1.4節。
本章首先討論Tomcat與HTTP伺服器整合的一般原理,然後介紹Tomcat與Apache以及IIS整合的詳細步驟。
22.1 Tomcat與HTTP伺服器整合的原理
Tomcat伺服器通過Connector連接器組件與客戶程式建立串連,Connector組件負責接收客戶的請求,以及把Tomcat伺服器的響應結果發送給客戶。預設情況下,Tomcat在server.xml中配置了兩種連接器:
<!-- Define a non-SSL Coyote HTTP/1.1
Connector on port 8080 -->
<Connector port="8080"
maxThreads="150"
minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false"
redirectPort="8443"
acceptCount="100"
debug="0"
connectionTimeout="20000"
disableUploadTimeout="true" />
<!-- Define a Coyote/JK2 AJP 1.3
Connector on port 8009 -->
<Connector port="8009"
enableLookups="false"
redirectPort="8443" debug="0"
protocol="AJP/1.3" />
第一個連接器監聽8080連接埠,負責建立HTTP串連。在通過瀏覽器訪問Tomcat伺服器的Web應用時,使用的就是這個連接器。
第二個連接器監聽8009連接埠,負責和其他的HTTP伺服器建立串連。在把Tomcat與其他HTTP伺服器整合時,就需要用到這個連接器。
Web客戶訪問Tomcat伺服器上JSP組件的兩種方式22-1所示。
圖22-1 Web客戶訪問Tomcat伺服器上的JSP組件的兩種方式
在圖22-1中,Web客戶1直接存取Tomcat伺服器上的JSP組件,他訪問的URL為http://localhost:8080/index.jsp。Web客戶2通過HTTP伺服器訪問Tomcat伺服器上的JSP組件。假定HTTP伺服器使用的HTTP連接埠為預設的80連接埠,那麼Web客戶2訪問的URL為http://localhost:80/index.jsp 或者 http://localhost/index.jsp。
下面,介紹Tomcat與HTTP伺服器之間是如何通訊的。
22.1.1 JK外掛程式
Tomcat提供了專門的JK外掛程式來負責Tomcat和HTTP伺服器的通訊。應該把JK外掛程式安置在對方的HTTP伺服器上。當HTTP伺服器接收到客戶請求時,它會通過JK外掛程式來過濾URL,JK外掛程式根據預先配置好的URL映射資訊,決定是否要把客戶請求轉寄給Tomcat伺服器處理。
假定在預先配置好的URL映射資訊中,所有"/*.jsp"形式的URL都由Tomcat伺服器來處理,那麼在圖22-1的例子中,JK外掛程式將把客戶請求轉寄給Tomcat伺服器,Tomcat伺服器於是運行index.jsp,然後把響應結果傳給HTTP伺服器,HTTP伺服器再把響應結果傳給Web客戶2。
對於不同的HTTP伺服器,Tomcat提供了不同的JK外掛程式的實現模組。本章將用到以下JK外掛程式:
與Windows下的Apache HTTP伺服器整合:mod_jk_2.0.46.dll
與Linux(RedHet)下的Apache HTTP伺服器整合:mod_jk.so-ap2.0.46-rh72..46-rh72
與IIS伺服器整合:isapi_redirect.dll
22.1.2 AJP協議
AJP是為Tomcat與HTTP伺服器之間通訊而定製的協議,能提供較高的通訊速度和效率。在配置Tomcat與HTTP伺服器整合中,讀者可以不必關心AJP協議的細節。關於AJP的知識也可以參考網址:
http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk2/doc/common/AJPv13.html
22.2 在Windows下Tomcat與Apache伺服器整合
Apache HTTP伺服器是Apache軟體組織提供的開放原始碼軟體,它是一個非常優秀的專業的Web伺服器,為網路系統管理員提供了豐富多彩的Web管理功能,包括目錄索引、目錄別名、內容協商、可配置的HTTP錯誤報表、CGI程式的SetUID執行、子進程資源管理、伺服器端影像對應、重寫URL、URL拼字檢查以及線上手冊等。
Apache HTTP伺服器本身沒有提供Servlet/JSP容器。因此,在實際應用中,把Tomcat與Apache整合,可以建立具有實用價值的商業化的Web平台。在Windows NT/2000下Tomcat與Apache伺服器整合需要準備的軟體參見表22-1。
表22-1 在Windows NT/2000下Tomcat與Apache伺服器整合需要準備的軟體
軟 件 下 載 位 置 本書配套 光碟片上的位置
基於Windows NT/2000的 Apache HTTP伺服器軟體 http://httpd.apache.org /download.cgi software/apache_2.0.47- win32-x86-no_ssl.msi
JK外掛程式 http://jakarta.apache.org/builds /jakarta-tomcat-connectors/jk lib/ mod_jk_2.0.46.dll
1、安裝Apache HTTP伺服器
運行apache_2.0.47-win32-x86-no_ssl.msi,就啟動了Apache HTTP伺服器的安裝程式,只要按預設設定進行安裝即可。如果安裝成功,會自動在Windows中加入Apache HTTP服務,22-2所示。
圖22-2 加入到Windows服務中的Apache服務
假定Apache的根目錄為,在其conf子目錄下有一個設定檔httpd.conf。如果Apache安裝在本機,並且採用預設的80連接埠作為HTTP連接埠,在httpd.conf檔案中會看到如下屬性:
Listen 80
ServerName localhost:80
在作業系統的【開始】→【程式】→【Apache HTTP Server 2.0.47】→【Control Apache Server】菜單中,提供了重啟(Restart)、啟動(Start)和關閉(Stop)Apache伺服器的子功能表。
應該確保80連接埠沒有被佔用,否則Apache伺服器無法啟動。Apache伺服器啟動後,就可以通過訪問Apache的測試頁來確定是否安裝成功。訪問http://localhost,如果出現22-3所示的網頁,就說明Apache已經安裝成功了。
圖22-3 Apache伺服器的測試網頁
2、在Apache中加入JK外掛程式
在Apache中加入JK外掛程式,只要把mod_jk_2.0.46.dll拷貝到/modules目錄下即可。
3、建立workers.properties檔案
workers.properties檔案用於配置Tomcat的資訊,它的存放位置為 /conf/workers.properties。在本書配套光碟片的sourcecode/chapter22/windows_apache目錄下提供了workers.properties檔案,它的內容如下("#"後面為注釋資訊):
workers.tomcat_home=C:/jakarta-tomcat
#讓mod_jk模組知道Tomcat
workers.java_home=C:/j2sdk1.4.2
#讓mod_jk模組知道j2sdk
ps=/
#指定檔案路徑分割符
worker.list=worker1
worker.worker1.port=8009
#工作連接埠,若沒佔用則不用修改
worker.worker1.host=localhost
#Tomcat伺服器的地址
worker.worker1.type=ajp13
#類型
worker.worker1.lbfactor=1
#Server Load Balancer因數
以上檔案中的屬性描述參見表22-2。
表22-2 workers.properties檔案的屬性
屬 性 描 述
workers.tomcat_home 指定Tomcat伺服器的根目錄
workers.java_home 指定JDK的根目錄
worker.list 指定Tomcat伺服器工作名單
worker.worker1.port 指定Tomcat伺服器使用的JK 連接埠
worker.worker1.host 指定Tomcat伺服器的IP地址
worker.worker1.type 指定Tomcat伺服器 與Apache之間的通訊協定
worker.worker1.lbfactor 指定Server Load Balancer因數(Load Balance Factor)。 只有在使用了Server Load Balancer器 (LoadBalancer)的情況下, 這個屬性才有意義
4、修改Apache的設定檔httpd.conf
開啟/conf/httpd.conf檔案,在其末尾加入以下內容:
# Using mod_jk2.dll to
redirect dynamic calls to Tomcat
LoadModule jk_module
modules/mod_jk_2.0.46.dll
JkWorkersFile
"conf/workers.properties"
JkLogFile "logs/mod_jk2.log"
JkLogLevel debug
JkMount /*.jsp worker1
JkMount /helloapp/* worker1
在本書配套光碟片的sourcecode/chapter22/windows_apache/httpd_modify.conf檔案中提供了以上內容,它指示Apache伺服器載入JK外掛程式,並且為JK外掛程式設定相關屬性,這些屬性的描述參見表22-3。
表22-3 JK外掛程式的相關屬性
屬 性 描 述
LoadModule 指定載入的JK外掛程式
JkWorkersFile 指定JK外掛程式的工作檔案
JkLogFile 指定JK外掛程式使用的記錄檔, 在實際配置中,可以通過查看這個記錄檔, 來跟蹤JK外掛程式的運行過程, 這對排錯很有用
JkLogLevel 指定JK外掛程式的記錄層級, 可選值包括debug、info和error等
JkMount 指定JK外掛程式處理的URL映射資訊
JkMount用來指定URL映射資訊,"JkMount /*.jsp worker1"表示"/*.jsp"形式的URL都由worker1代表的Tomcat伺服器來處理;"JkMount /helloapp/* worker1"表示訪問helloapp應用的URL都由worker1來處理。
5、測試組態
重啟Tomcat伺服器和Apache伺服器,通過瀏覽器訪問http://localhost/index.jsp,如果出現Tomcat的預設首頁,說明配置已經成功。此外,如果在Tomcat伺服器上已經發布了helloapp應用,可以訪問http://localhost/helloapp/index.htm,如果正常返回helloapp應用的index.htm網頁,說明配置已經成功。
如果配置有誤,可以查看JK外掛程式產生的日誌資訊,它有助於尋找錯誤原因。在Apache的設定檔httpd.conf中設定該記錄檔的存放位置為/logs/mod_jk2.log
Apache與多個Tomcat伺服器整合時的Server Load Balancer
在實際應用中,如果網站的訪問量非常大,為了提高訪問速度,可以將多個Tomcat伺服器與Apache整合,讓它們共同分擔運行Servlet/JSP組件的任務。 JK外掛程式的loadbalancer(Server Load Balancer器)負責根據在workers.properties檔案中預先配置的lbfactor(Server Load Balancer因數)為這些Tomcat伺服器分配工作負載,實現Server Load Balancer。
假定Apache和兩個Tomcat伺服器整合,一個Tomcat伺服器和Apache運行在同一台機器上,使用的JK連接埠為8009,還有一個Tomcat伺服器運行在另一台機器上,主機名稱為anotherhost,使用的JK連接埠為8009。以下是把Apache和這兩個Tomcat伺服器整合的步驟。
(1)把mod_jk_2.0.46.dll拷貝到/lib目錄下。
(2)在/conf目錄下建立如下的workers.properties檔案(注意粗體部分的內容):
ps=/
#指定檔案路徑分割符
worker.list=worker1,
worker2,loadbalancer
worker.worker1.port=8009
#工作連接埠,若沒佔用則不用修改
worker.worker1.host=localhost
#Tomcat伺服器的地址
worker.worker1.type=ajp13
#類型
worker.worker1.lbfactor=100
#Server Load Balancer因數
worker.worker2.port=8009
#工作連接埠,若沒佔用則不用修改
worker.worker2.host=anotherhost
#Tomcat伺服器的地址
worker.worker2.type=ajp13
#類型
worker.worker2.lbfactor=100
#Server Load Balancer因數
worker.loadbalancer.type=lb
worker.loadbalancer.
balanced_workers=worker1, worker2
以上檔案建立了兩個worker:worker1和worker2分別代表兩個Tomcat伺服器,它們由worker.loadbalancer來分配工作負載。
(3)修改/conf/httpd.conf檔案,在檔案末尾加入如下內容:
# Using mod_jk2.dll to
redirect dynamic calls to Tomcat
LoadModule jk_module
modules/mod_jk_2.0.46.dll
JkWorkersFile "conf/workers.properties"
JkLogFile "logs/mod_jk2.log"
JkLogLevel debug
JkMount /*.jsp loadbalancer
JkMount /helloapp/* loadbalancer
當客戶請求"/*.jsp"或"/helloapp/*"形式的URL,該請求都由loadbalancer來負責轉寄,它根據在workers.properties檔案中為worker1和worker2分配的lbfactor屬性,來決定如何調度它們。
只有在使用了loadbalancer的情況下,workers.properties檔案中worker的lbfactor屬性才有意義,lbfactor取值越大,表示分配給Tomcat伺服器的工作負載越大。
(4)修改兩個Tomcat伺服器的JK連接埠,確保它們和workers.properties檔案中的配置對應。此外,在使用了loadbalancer後,要求worker的名字和Tomcat的server.xml檔案中的元素的jvmRoute屬性一致。
所以應該分別修改兩個Tomcat的sever.xml檔案,把它們的元素的jvmRoute屬性分別設為worker1和worker2。以下是修改後的兩個Tomcat伺服器的元素:
Tomcat伺服器1:
<Engine name="Catalina"
defaultHost="localhost"
debug="0" jmvRoute="worker1">
Tomcat伺服器2:
<Engine name="Catalina"
defaultHost="localhost"
debug="0" jmvRoute="worker2">
(5)在完成以上步驟後,分別啟動兩個Tomcat伺服器和Apache伺服器,然後訪問http://localhost/index.jsp,會出現Tomcat伺服器的預設首頁。由於此時由loadbalancer來調度Tomcat伺服器,因此不能斷定到底訪問的是哪個Tomcat伺服器的index.jsp,這對於Web客戶來說是透明的。
如果在進行以上實驗時,兩個Tomcat伺服器都在同一台機器上運行,應該確保它們沒有使用相同的連接埠。在Tomcat的預設的server.xml中,一共配置了以下3個連接埠:
<Server port="8005"
shutdown="SHUTDOWN" debug="0">
<!-- Define a non-SSL Coyote
HTTP/1.1 Connector on port 8080 -->
<Connector port="8080" />
<!-- Define a Coyote/JK2
AJP 1.3 Connector on port 8009 -->
<Connector port="8009" />
如果兩個Tomcat伺服器都在同一台機器上運行,則至少應該對其中一個Tomcat伺服器的以上3個連接埠號碼都進行修改。
此外,如果把Tomcat和其他HTTP伺服器整合,Tomcat主要負責處理HTTP伺服器轉寄過來的客戶請求,通常不會直接接受HTTP請求。因此為了提高Tomcat的運行效能,可以關閉Tomcat的HTTP連接器,方法為在server.xml中把Tomcat的HTTP Connector的配置注釋掉。