首頁
中文書目錄
原文書目錄
 站內快速搜尋
資源中心
Book Series
Special Interest













■好消息,歐萊禮書籍已重新鋪貨至各大書局及網路書店,歡迎讀者選購       ■歡迎各院校採用歐萊禮書籍,學校團購請洽校園服務團隊

[書籍導讀]

Tomcat 技術手冊


Tomcat 設定技巧 - Top 10
作者:Jason Brittain & Ian F. Darwin

出處:http://www.onjava.com/lpt/a/3909

按:現在開發 Java Web 應用,已是建立和部署 Web 內容常用的方式。全球的使用者漸漸發現到以 Jakarta Tomcat 作為 Servlet 和 JSP container 的好處。Tomcat 是自由軟體、跨平臺、有許多功能特色,並且發展迅速,現在已十分地流行。

唯一的環節就是:如何按照你的需求去設定 Tomcat 呢?只要你能設定到符合要求,Tomcat 必能如你所願。下面是十項關於 Tomcat 的組態設定技巧,這些技巧源自於筆者拙著《Tomcat: The Definitive Guide》(中文版《Tomcat 技術手冊),希望對你有所幫助。 - Jason Brittain

1. 設定 Admin Web Application
大多數商用的 J2EE 伺服器都會提供全功能的管理界面,而且許多界面還可以經由 web 應用程式來存取。Tomcat Admin 應用程式也快要成為全功能的 Tomcat 管理工具,以與這些商用產品相庭抗禮。此程式首先出現在 Tomcat 4.1 中,並且已能提供範圍、資料來源、以及使用者與群組的控制。你也可以控制像初始化參數,以及在各種不同的使用者資料庫中的使用者、群組、與角色。在未來的發行版中,其功能還會再加強,不過,目前的實作已經證實是相當有用的。

Admin web 應用程式是定義在 CATALINA_BASE/webapps/admin.xml 中。
你必須編輯此檔,以確保在 Context 元素的 docBase 標記屬性中所設定的路徑是絕對的,亦即,CATALINA_HOME/server/webapps/manager 的絕對路徑(譯註:CATALINA_HOME 即 tomcat 安裝目錄)。另一種方式是,你可以移除自動部署的檔案,並在 server.xml 檔中手動地設定 Admin 範圍。在不會被此應用程式管理的機器上,應該可以刪除 CATALINA_BASE/webapps/admin.xml 來停用它。
如果使用 UserDatabaseRealm(預設),就需要新增一個使用者以及一個角色到 CATALINA_BASE/conf/tomcat-users.xml 檔中。現在,請編輯這個檔,加入「admin」角色到使用者資料庫中,如下:

<role name="admin"/>

另外還要一個設定為「admin」角色的使用者。請於現有的使用者資料之後,加入以下這一行(請改變密碼使其更加安全):

<user name="admin" password="deep_dark_secret" roles="admin"/>

完成這些步驟後,請重新啟動 Tomcat,並連到 http://localhost:8080/admin,你將看到一個登入畫面。Admin 應用程式係使用容器管理的安全機制,並以 Jakarta Struts 的架構編寫。一旦以設定為「admin」角色的使用者登入,即能夠使用 Admin 管理界面設定 Tomcat 的組態。

2. 設定 Manager 應用程式
Manager 應用程式讓你能透過比 Admin 應用程式更簡化的使用者界面,來執行簡單的管理作業。

Manager 應用程式係定義於自動部署檔 CATALINA_BASE/webapps/manager.xml 之內。
你必須編輯此檔案,確保 Context 元素的 docBase 標記屬性是絕對路徑,亦即,CATALINA_HOME/server/webapps/manager 的絕對路徑。
如果是使用預設的 UserDatabaseRealm,則需要新增使用者和角色到 CATALINA_BASE/conf/tomcat-users.xml 檔中。請編輯此檔案,新增「manager」角色到使用者資料庫中:

<role name="manager">

再來也要有一個設定為「manager」角色的使用者。在現成的使用者區塊之後加入如下的內容(記得將密碼改成比較安全的):

<user name="manager" password="deep_dark_secret" roles="manager"/>

然後重新啟動 Tomcat,連上 http://localhost/manager/list,將看到樸素的文字式管理界面,或連上 http://localhost/manager/html/list,可看到簡單的 HMTL 管理界面。不管是哪種方式都說明你的 Manager 現在已經啟動了。

Manager 應用程式讓你以非持續性的方式安裝新的 web 應用程式,亦即,作為測試用。如果在 /home/user/hello 中有一 web 應用程式,並想藉著安裝在 URI /hello 下來測試,我們在第一個文字輸入欄位(Path)中輸入「/hello」,而在第二個文字輸入欄位(Config URL)中輸入「file:/home/ian/webs/hello」。

Manager 也能讓你停止、重新載入、刪除、或解除 web 應用程式的部署。停止應用程式會讓它無法使用,直到收到進一步的通知,不過,它當然也可以再啟動。使用者企圖存取已經停止的應用程式,將會收到錯誤訊息,如「503 - This application is not currently available」。

刪除 web 應用程式只會從 Tomcat 的現行分身中刪除 — 如果此應用程式是從組態檔啟動的,則下次再啟動 Tomcat 時,它還會再出現(亦即,刪除動作並不會自硬碟中刪除 web 應用程式的內容)。

3. 部署 web 應用程式
有兩種自動部署 web 應用程式於檔案系統上的方式:

1. 將 WAR 檔或 web 應用程式的目錄(包括所有的內容)複製到 $CATALINA_BASE/webapps 目錄中。

2. 建立只包含 web 應用程式之 Context 元素的 XML 程式片段,並將其放入 $CATALINA_BASE/webapps 中。web 應用程式本身可以存放於檔案系統中的任何位置。

如果有 WAR 檔,只需將其複製到 CATALINA_BASE/webapps 目錄中,就可部署它。檔案名稱必須以 .war 作為副檔名。當 Tomcat 發現此檔時,它(預設)會將其解開至以 WAR 檔之主檔名為名稱的子目錄中。接著,則會在記憶體中建立範圍,正如藉著編輯 Tomcat 的 server.xml 檔而產生的一樣。不過,任何必要的預設值則會來自 Tomcat 的 server.xml 檔中的 DefaultContext 元素。

部署 web 應用程式的另一種方式是撰寫 Context 的 XML 程式片段檔,然後將該檔複製到 CATALINA_BASE/webapps 目錄下。範圍的片段並不是完整的 XML 文件,而只是適合於 web 應用程式之 Context 元素及任何子元素。這些檔案就像從 server.xml 檔中切出的 Context 元素一樣,因此稱為範圍的片段。

例如,如果想要部署 MyWebApp.war 的 WAR 檔,和可存取部分該 web 應用程式的領域,則可以使用這樣的程式片段:

<!--
  部署 MyWebApp.war 的範圍片段
-->
<Context path="/demo" docBase="webapps/MyWebApp.war"
      debug="0" privileged="true">
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
      resourceName="UserDatabase"/>
</Context>

請將此片段程式檔命名為 MyWebApp.xml,然後複製到 CATALINA_BASE/webapps 目錄下。
這些範圍片段提供了一種部署 web 應用程式的方便方法;不需要編輯 server.xml 檔,而且除非關閉預設的 liveDeploy 功能,否則不需再啟動 Tomcat 以安裝新的 web 應用程式。

4. 設定虛擬主機
只有在架設虛擬主機時,才需要修改 Host 元素。虛擬主機是一種機制,可以讓一個 web 伺服器行程服務多個網域名稱,而讓各個網域看來有其自己的伺服器。事實上,由於將電腦直接連上網際網路,並以足夠的頻寬提供合理的回應時間,以及使用固定的 IP 位址提供穩定度,所需花費的成本太高,因此大多數的小型商業網站都實作成虛擬主機。

在任何 web 伺服器上,藉著在「網域名稱服務」(Domain Name Service;DNS)資料中設定另一個 IP 位址,並告訴 web 伺服器將所有此位址的請求對應至特定的網頁目錄,就可以產生「以名稱為基準」的虛擬主機。因為這本書是談論 Tomcat,所以我們不會敘述在不同作業系統上設定 DNS 資料的全部方法。如果需要這方面的協助,請參閱由 Paul Albitz 與 Cricket Liu 合著的《DNS and Bind》(O'Reilly 出版)。我們會使用靜態的 hosts 檔作為示範,因為這是設定主機別名來測試的最簡單辦法。

如欲在 Tomcat 中使用虛擬主機,你只需設定主機的 DNS 或 hosts 資料。設定 localhost 的 IP 別名,以足夠來測試了。然後,你需要在 server.xml 的組態檔中加入幾行資料:

<Server port="8005" shutdown="SHUTDOWN" debug="0">
   <Service name="Tomcat-Standalone">
   <Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
  port="8080" minProcessors="5" maxProcessors="75"
  enableLookups="true" redirectPort="8443"/>
   <Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
  port="8443" minProcessors="5" maxProcessors="75"
  acceptCount="10" debug="0" scheme="https" secure="true"/>
    <Factory className="org.apache.coyote.tomcat4.CoyoteServerSocketFactory"
  clientAuth="false" protocol="TLS" />
  </Connector>
   <Engine name="Standalone" defaultHost="localhost" debug="0">
   <!--此為預設主機-->
   <Host name="localhost" debug="0" appBase="webapps"
   unpackWARs="true" autoDeploy="true">
    <Context path="" docBase="ROOT" debug="0"/>
    <Context path="/orders" docBase="/home/ian/orders" debug="0" reloadable="true" crossContext="true">

    </Context>
   </Host>
  <!--此為第一個「虛擬主機」www.example.com -->
  <Host name="www.example.com" appBase="/home/example/webapp">
  <Context path="" docBase="."/>
  </Host>

   </Engine>
  </Service>
</Server>

在發行時,Tomcat 的 server.xml 檔只含有一個虛擬主機,不過要加入額外的虛擬主機是相當容易的。在前面的範例中,server.xml 檔的簡化版本以粗體字顯示新增一個虛擬主機所需的所有額外結構。每一個 Host 元素至少必須含有一個 Context 元素;其中之一必須是此主機預設的 Context,其設定方式是將相對路徑設為空字串。(例如,path="")。

5. 設定基礎驗證(Basic Authentication)
當存取受保護的資源時,容器管理的驗證方法可以控制確認使用者身分的方式。當 web 應用程式使用基本驗證(在 web.xml 檔之 auth-method 元素中的 BASIC)時,每當瀏覽器請求該受保護的 web 應用程式資源時,Tomcat 會使用 HTTP 基本驗證向瀏覽器索取使用者名稱與密碼。使用這種驗證方法,所有的密碼都會以 base64 編碼的文字在網路上傳遞。

提醒:一般認為使用基本驗證是安全防護上的瑕疵,除非在用戶端與伺服端之間,網站也同時使用 HTTPS 或其它的加密方式(如虛擬私有網路;VPN)。如果沒有這種額外的加密機制,網路上的駭客可以攔截(甚至濫用)使用者密碼。但是,如果你剛開始使用 Tomcat,或者想要以 web 應用測試容器管理的安全防護,基礎驗證非常容易設定和使用。只需要加入 <security-constraint><login-config> 元素到 web 應用的 web.xml 檔中,並於 CATALINA_BASE/conf/tomcat-users.xml 中加入適當的 <role><user> 元素即可,然後重新啟動 Tomcat,剩下的 Tomcat 會幫你解決。

範例 2-6 係節錄自擁有會員獨享的子目錄(使用基本驗證)之俱樂部會員網站的 web.xml。請注意實質上這會取代 Apache web 伺服器的 .htaccess 檔。

<!--
  定義會員獨享區 — 定義此應用程式的「Security Constraint」
  並將其對應至想要限制的子目錄(URL)
-->
<security-constraint>
  <web-resource-collection>
   <web-resource-name>
    Entire Application
   </web-resource-name>
   <url-pattern>/members/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
   <role-name>member</role-name>
  </auth-constraint>
</security-constraint>
<!-- Define the Login Configuration for this Application -->
<login-config>
 <auth-method>BASIC</auth-method>
 <realm-name>My Club Members-only Area</realm-name>
</login-config>

6. 單一入口(Single Sign-On)
當設定好領域及驗證方法後,你將需要處理實際的登入過程。通常對使用者來說,登入應用程式是很令人討厭的,因此你需要盡量減少必須驗證身分的次數。在預設狀況下,每個 web 應用程式會要求使用者在第一次請求受保護的資源時登入。如果你執行多個 web 應用程式,而每個程式都要求使用者驗明身分,這對使用者來說是很煩人的。使用者無法知道有多少個別的應用程式構成任何單一的網站,所以也不會知道正在請求跨越範圍邊界的資源,而會懷疑為何要重複地登入。

Tomcat 4 的「單一入口」功能可以讓使用者只需驗明身分一次。就可存取所有載入虛擬主機的 web 應用程式。如欲使用這個功能,你只需在主機的層次加入 SingleSingOnValve 元素,如下所示:

<Valve className="org.apache.catalina.authenticator.SingleSignOn"
    debug="0"/>

Tomcat 發行版的預設 server.xml 檔含有被加上註解符號的單一入口的 Valve 組態範例,你可以移除註解符號並使用之。此後,在所設定虛擬主機內,任何在某範圍中被視為合法的使用者,在同一主機之所有其它範圍內都會被視為合法。

使用單一入口的門閥(valve)有一些重要的限制:
  • Valve 必須被設定,並與 web 應用程式(以 Context 元素表示)皆套疊於相同的 Host 元素內
  • 包含共享的使用者資訊的 Realm 必須設定在相同的 Host 層級,或設定在外一層。
  • Context 層級時,Realm 不能被覆蓋。
  • 使用單一入口的 web 應用程式必須使用 Tomcat 內建的驗證方式之一(在 web.xmlauth-method 元素中),而非自訂的驗證方式。內建的方法包括基本、摘要、表單、及 client-cert 驗證。
  • 如果使用單一入口,並想要在網站中整合其它第三者的 web 應用程式,而且此新的 web 應用程式使用自己的驗證程式,但不使用容器管理的安全防護機制,基本上是作不到的。對所有使用單一入口的 web 應用程式,使用者需要登入一次,然後當他們請求新的第三者的 web 應用程式時,還要再登入一次。如果你有原始程式碼,而且又是開發者,當然可以修改它,可是這可能不太容易。
  • 單一入口的門閥需要使用 HTTP 的 cookie。
7. 自訂的使用者目錄(Customized User Directores)
某些網站喜歡讓個別的使用者在伺服器上發佈網頁目錄。例如,大學的學系可能會給每個學生一個公用區域,或 ISP 會在一台伺服器上釋放一些網頁空間給沒有虛擬主機的客戶。在這種情況下,一般會使用 ~ 字元加上使用者的名稱,作為該使用者網站的虛擬路徑:

http://www.cs.myuniversity.edu/~username
http://members.mybigisp.com/~username

Tomcat 提供兩種方式,依據主機來對應,它使用幾個特殊的 Listener 元素。ListenerclassName 標記屬性應為 org.apache.catalina.startup.UserConfig,而 userClass 標記屬性則指定一種對應的類別。如果你的作業系統是 Unix、並有執行 Tomcat 的帳號可讀取的標準 /etc/passwd 檔、而且該檔案設定使用者的主目錄,則請使用 PasswdUserDatabase 對應類別:

<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html"
userClass="org.apache.catalina.startup.PasswdUserDatabase"/>

Web 檔案必須放入如 /home/users/ian/public_html /users/jbrittain/public_html 目錄中。當然,你可以將 public_html 改成使用者置放其個人網頁的任何子目錄。

事實上,此目錄可以完全不在使用者的主目錄內。如果你沒有密碼檔,但想要從使用者名稱對應至有共同父目錄(如 /home)的子目錄,請用 HomeUserDatabase 類別:

<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html" homeBase="/home"
userClass="org.apache.catalina.startup.HomesUserDatabase"/>

在此情況下,web 檔案會放入如 /home/ian/public_html/home/jbrittain/public_html 的目錄中。這種格式在 Windows 比較有用,你可以使用像 C:\home 的目錄。

如果存在時,這些 Listener 元素必須放在 Host 元素內,但不能在 Context 元素內,因為 Listener 元素是套用至 Host 本身。

8. 在 Tomcat 中使用 CGI
Tomcat 主要的目的是作為 servlet/JSP 引擎,不過它卻含有大量的功能可以與傳統的 web 伺服器相抗衡。其中之一是對共用閘道界面(CGI)的支援;CGI 提供一種方式來執行外部程式,以回應瀏覽器的請求,而多半是用來處理網頁上的表單。CGI 之所以稱為通用,是因為它可以叫用以幾乎任何程式或 script 語言編寫的程式:Perl、Python、awk、Unix 的 shell script、甚至 Java。不過,由於啟動時的系統負載,你可能不會將 Java 應用程式當成 CGI 來執行;而 servlet 規格的原始設計就是要來消除這種系統負載。Servlet 幾乎永遠比 CGI 有效率,因為每次當有人點選連結或按鈕時,你並不會啟動新的作業系統層級的行程。

Tomcat 內含非必要性的 CGI servlet,以讓你執行舊式的 CGI script;前提是假設大多數新的後端處理都是交由使用者自訂的 servlet 與 JSP 來執行。

如欲啟用 Tomcat 的 CGI servlet,你必須執行下列的動作:
  1. servlets-cgi.renametojar(可在 CATALINA_HOME/server/lib/ 中找到)更名成 servlets-cgi.jar,以便讓處理 CGI script 的 servlet 會在 Tomcat 的 CLASSPATH 中。
  2. 在 Tomcat 的 CATALINA_BASE/conf/web.xml 檔中,移除 cgi servlet 的定義前的註解符號(在目前的發行版中,約於第 241 行)。
  3. 也是在 Tomcat 的 web.xml 檔中,移除 cgi servlet 的 servlet-mapping 元素的註解符號(在發行版中,大約於第 299 行)。請記住,這會設定指向 CGI script 的 HTML 連結。
  4. 將 CGI script 放在 WEB-INF/cgi 目錄之下(記住,WEB-INF 是將不想讓使用者看到的東西藏起來的安全地方),或放在範圍中其它的目錄中,並調整 cgiPathPrefix 參數,以識別包含檔案的目錄。這會設定 CGI script 的實際位置,而一般會與上一步驟的 URL 不同。
  5. 重新啟動 Tomcat,你的 CGI 處理作業就應該能運作了。
讓 servlet 尋找實際的 script 的預設目錄是 WEB-INF/cgi。如前所述,WEB-INF 目錄已受到保護,可防範瀏覽器的偷窺,因此這是置放 CGI script 的好地方,而這些 script 可能會包含密碼或其它機密的資訊。但是,為了維持與其它伺服器的相容性,你可能會偏好將 script 放在傳統的目錄 — /cgi-bin — 中,不過請注意,在此目錄中的檔案可能會被好奇的網際漫遊者看到。另外,在 Unix 上,請確定執行 Tomcat 的使用者有執行 CGI script 的權限。

9. 變更 Tomcat 的 JSP 編譯器
在 Tomcat 4.1(或更高版本),則是直接從 Tomcat 內使用 Ant 的程式控制器來編譯 JSP。這種作法好像有點奇怪,不過這也是 Ant 的功用之一;有一個 API 可讓開發者在不需啟動新的 JVM 的情形下,使用 Ant。這是以 Java 編寫 Ant 的好處之一。此外,這表示你現在可以使用 Ant 中之 javac 工作項目所支援的任何編譯器,這些編譯器列於 Apache Ant 手冊的 javac 文件頁面中。在使用上,這比較容易使用,因為你只需要稱為「compiler」的 init-parm,以及一個支援的編譯器名稱:


<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>
  <init-param>
   <param-name>compiler</param-name>
   <param-value>jikes</param-value>
  </init-param>
  <load-on-startup>3</load-on-startup>
</servlet>

當然,此編譯器必須安裝在系統上,而且也可能要設定 CLASSPATH


10. 限制特定主機存取
有時,你可能只想讓來自特定的主機名稱或 IP 位址的使用者,能存取 Tomcat 的 web 應用程式。這樣一來,就只有位於指定站點的客戶端能夠取得服務的內容了。Tomcat 內有兩個 Valve 可做此用途的設定:RemoteHostValveRemoteAddrValve

這些 Valve 可以讓你用主機名稱或 IP 位址來過濾請求,並允許或拒絕比對成功的主機。其功用類似於 Apache httpd 中,以目錄為基準的 Allow/Deny 指令。如果執行 Admin 應用程式,你可能想只允許從 localhost 來存取它,如下所示:

<Context path="/path/to/secret_files" ...>
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
    allow="127.0.0.1" deny=""/>
</Context>

如果未給定 allow 樣式,則會拒絕符合 deny 屬性的樣式,但允許所有其它的樣式。類似地,如果未給定 deny 樣式,則會允許符合 allow 屬性的樣式,但拒絕所有其它的樣式。

| 首頁 | 聯絡我們 |
© 2009, O'Reilly Media, Inc. Taiwan Branch