Tomcat設定ファイルserver.xmlを徹底解説:主要コンポーネントの役割と設定例

TomcatはApacheソフトウェア財団が開発するオープンソースの軽量Webアプリケーションサーバーであり、広く利用されています。server.xmlはTomcatにおいて最も重要な設定ファイルです。server.xmlの各要素は、Tomcatの各コンポーネントに対応しています

XMLファイル内の要素を設定することで、Tomcatの各コンポーネントを制御できます。したがって、server.xmlの設定を理解することは、Tomcatを正しく把握し活用するために不可欠です。

本稿では、設定例を交えながらserver.xml内の各コンポーネントの設定方法を紹介し、Tomcatの主要コンポーネントが担う役割と、それらの相互関係について詳しく説明します。

なお、server.xml内の要素はTomcatのコンポーネントに対応しているため、以後の説明では便宜上「要素」と「コンポーネント」を厳密に区別しません。

server.xmlの設定例

server.xmlは/TOMCAT_HOME/confディレクトリ配下に置かれます。以下がserver.xmlの設定例です。

<Server port="8006" shutdown="HALT">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserRegistry" 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 name="CoreService">
    <Connector protocol="HTTP/1.1" port="9090" redirectPort="9443" connectionTimeout="15000" />
    <Connector protocol="AJP/1.3" port="8011" redirectPort="9443" />
    <Engine name="CoreEngine" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserRegistry"/>
      </Realm>

      <Host name="localhost" appBase="deploy"
            unpackWARs="false" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="core_access_log." suffix=".log"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

server.xmlの要素分類と全体構造

server.xmlの全体構造

server.xmlの全体構造は次のようになります。

<Server>
    <Service>
        <Connector />
        <Connector />
        <Engine>
            <Host>
                <Context />  <!-- 現在は自動デプロイが一般的なため、Context要素の直接設定は非推奨。Contextの節で詳述 -->
            </Host>
        </Engine>
    </Service>
</Server>

この構造にはTomcatの主要コンポーネントだけが示されています。Tomcatにはこれ以外のコンポーネントも存在します。以下ではコンポーネントの分類を紹介します。

server.xmlの要素分類

server.xml内の要素は、次の4種類に分類できます。

(1)最上位要素:<Server>と<Service>

<Server>要素は設定ファイル全体のルート要素です。<Service>要素は、1つのEngine要素と、そのEngineに接続される一連のConnector要素の集まりを表します。

(2)コネクタ:<Connector>

<Connector>は、外部クライアントが特定のServiceへリクエストを送信するためのインターフェースです。同時に、外部クライアントが特定のServiceからレスポンスを受信するためのインターフェースでもあります。

(3)コンテナ:<Engine>、<Host>、<Context>

コンテナの機能は、Connectorが受け取ったリクエストを処理し、対応するレスポンスを生成することです。

Engine、Host、Contextはいずれもコンテナですが、対等な関係ではなく親子関係にあります。EngineはHostを含み、HostはContextを含みます。

1つのEngineコンポーネントは、Service内のすべてのリクエストを処理できます。

1つのHostコンポーネントは、特定の仮想ホスト宛てのすべてのリクエストを処理できます。

1つのContextコンポーネントは、特定のWebアプリケーション宛てのすべてのリクエストを処理できます。

(4)組み込みコンポーネント:コンテナの中に組み込むことができるコンポーネント。

実際には、Server、Service、Connector、Engine、Host、ContextがTomcatの最重要かつ中核的なコンポーネントであり、その他のコンポーネントはすべて組み込みコンポーネントに分類できます。

主要コンポーネント

Server

Server要素は最上位に位置し、Tomcatコンテナ全体を表します。したがって、server.xmlの中で唯一の最外郭要素でなければなりません。

1つのServer要素には、1つ以上のService要素を含めることができます。

冒頭の設定例では、最外郭に<Server>要素が1つあります。shutdown属性はServerを停止するためのコマンドを表し、port属性はServerがshutdownコマンドを受け取るポート番号を表します。port属性を-1に設定すると、このポートを無効化できます。

Serverの主な役割は、クライアントがService群へアクセスできるようにするインターフェースを提供することと、自身が保持するすべてのServiceのライフサイクル(初期化方法、サービス終了方法、クライアントがアクセスしようとするServiceの特定方法など)を管理することです。

Service

Serviceは、ConnectorとEngineを外側から包み込み、それらを1つに組み立てて外部へサービスを提供する役割を持ちます。

1つのServiceには複数のConnectorを含められますが、Engineは1つだけです。

Connectorはクライアントからリクエストを受け取る役割を担い、Engineは受け取ったリクエストを処理する役割を担います。

冒頭の設定例では、Serverの中に「CoreService」という名前のServiceが含まれています。Tomcatは複数のServiceを提供することができ、異なるServiceを異なるポートでリッスンさせることも可能です。詳細は後述します。

Connector

Connectorの主な機能は、接続リクエストを受け取り、リクエスト元とデータをやり取りするためのRequestオブジェクトとResponseオブジェクトを生成することです。

その後、Engineがこのリクエストを処理するためのスレッドを割り当て、生成したRequestオブジェクトとResponseオブジェクトをEngineへ渡します。

Connectorの設定により、Serviceへアクセスするためのプロトコルとポート番号を制御できます。冒頭の設定例では、Serviceに2つのConnectorが含まれています。

<Connector protocol="HTTP/1.1" port="9090" redirectPort="9443" connectionTimeout="15000" />
<Connector protocol="AJP/1.3" port="8011" redirectPort="9443" />

(1)1つ目のConnectorの設定により、クライアントはポート9090番でHTTPプロトコルを使ってTomcatにアクセスできます。

protocol属性はリクエストのプロトコルを規定し、port属性はリクエストを受け付けるポート番号を規定します。redirectPort属性は、HTTPSへの切り替えが要求されているにもかかわらずHTTPでリクエストが届いた場合に、ポート9443番のConnectorへリダイレクトすることを示します。connectionTimeout属性は接続のタイムアウト時間です。

この例では、TomcatはHTTPリクエストを正式な80番ポートではなく9090番ポートで受け付けています。実際の本番環境でも、Tomcatは80番ポートではなく8080番ポートをリッスンしていることがよくあります。

本番環境ではTomcatを直接外部へ公開することはまれで、Tomcatとクライアントの間にnginxなどのプロキシサーバーを配置し、リクエスト転送、ロードバランシング、静的ファイル処理などを担当させることが一般的です。プロキシサーバーを経由してTomcatへアクセスする場合はLAN内の通信になるため、8080番ポートのまま利用されるケースが多いのです。

(2)2つ目のConnectorの設定により、クライアントはポート8011番でAJPプロトコルを使ってTomcatにアクセスできます。

AJPプロトコルは、Apacheなどの他のHTTPサーバーとの接続を担当します。Tomcatを他のHTTPサーバーと統合する場合、このコネクタが必要になります。

Tomcatを他のサーバーと統合する理由は、TomcatはServlet/JSPコンテナとして優れている一方、静的リソースの処理速度はApacheやIISといったHTTPサーバーに及ばないためです。そこでTomcatをServletコンテナとして使い、Apache側で静的リソースを処理するという役割分担がしばしば行われます。AJPプロトコルは、そのTomcatとApacheの間の接続を担います。

Engine

EngineコンポーネントはServiceコンポーネントの中にただ1つだけ存在し、Service内でリクエストを処理するコンポーネントです。

Engineコンポーネントは、1つまたは複数のConnectorからリクエストを受け取って処理し、処理済みのレスポンスをConnectorへ返し、最終的にクライアントへ届けます。

前述のとおり、Engine、Host、Contextはいずれもコンテナですが、対等な関係ではなく親子関係にあります。EngineはHostを含み、HostはContextを含みます。

冒頭の設定例では、Engineは次のように設定されています。

<Engine name="CoreEngine" defaultHost="localhost">

name属性はログやエラーメッセージに使用され、Server全体の中で一意である必要があります。

defaultHost属性はデフォルトのホスト名を指定します。サーバー宛てに届いたリクエストの中で、指定されたhost名に一致するものが存在しない場合、defaultHostで指定されたHostが処理を行います。

そのため、defaultHostの値は、Engine内のいずれかのHost要素のname属性値と一致していなければなりません。

Host

(1)EngineとHost

HostはEngineの子コンテナです。Engineコンポーネントには1つ以上のHostコンポーネントを組み込むことができ、各HostコンポーネントはEngine内の1つの仮想ホストを表します

Hostコンポーネントは最低1つ必要であり、そのうちの1つのname属性はEngineのdefaultHost属性と一致していなければなりません。

(2)Hostの役割

仮想ホストとしてのHostは、複数のWebアプリケーション(1つのContextが1つのWebアプリケーションを表します)を実行し、それらのインストール、展開、開始、終了を管理する役割を持ちます。

Hostコンポーネントが表す仮想ホストは、サーバー上のネットワーク上の名前エンティティ(例:「www.example.com」やIPアドレス「116.25.25.25」)に対応します。ユーザーがネットワーク名でTomcatサーバーに接続できるようにするには、この名前をDNSサーバーへ登録しておく必要があります。

クライアントは通常、接続先サーバーを識別するためにホスト名を使用し、そのホスト名はHTTPリクエストヘッダに含まれます。TomcatはHTTPヘッダからホスト名を抽出し、名前が一致するHostを探します。

一致するHostがない場合、リクエストはデフォルトホストへ送信されます。このためデフォルトホストは、DNSサーバーに登録されたネットワーク名である必要はありません。どのHostの名前とも一致しないリクエストは、すべてデフォルトホストへルーティングされるからです。

(3)Hostの設定

冒頭の設定例では、Hostは次のように設定されています。

<Host name="localhost" appBase="deploy" unpackWARs="false" autoDeploy="true">

各属性の意味は次のとおりです。

name属性は、仮想ホストのホスト名を指定します。Engine内で、name属性がEngineのdefaultHost属性と一致するHostはただ1つだけです。

通常、ホスト名はDNSサーバーに登録されたネットワーク名である必要がありますが、EngineのdefaultHostに指定された名前はその限りではありません。その理由は前述のとおりです。

unpackWARs属性は、Webアプリケーションを表すWARファイルを展開するかどうかを指定します。trueなら展開後のファイル構造を使ってWebアプリケーションを実行し、falseならWARファイルのままWebアプリケーションを実行します。

HostのautoDeploy属性とappBase属性は、Host内のWebアプリケーションの自動デプロイに関係します。この設定例には登場していませんが、xmlBase属性やdeployOnStartup属性も自動デプロイに関係する属性です。

Context

(1)Contextの役割

Context要素は、特定の仮想ホスト上で動作する1つのWebアプリケーションを表します。

以降、Context、アプリケーション、Webアプリケーションという語は、いずれもWebアプリケーションを指すものとします。各WebアプリケーションはWARファイル、またはWARファイルを展開して得られるディレクトリ(アプリケーションディレクトリ)を基盤とします。

ContextはHostの子コンテナであり、各Hostには任意の数のContext要素を定義できます。

冒頭の設定例では、server.xmlの中にContext要素の設定が存在しないことにお気づきでしょう。これはTomcatの自動デプロイが有効になっているためです。Webアプリケーションはserver.xmlに静的に定義されるのではなく、Tomcatの自動デプロイ機能によって一定の規則に従い配置されます。以下では、TomcatがWebアプリケーションを自動デプロイする仕組みを説明します。

(2)Webアプリケーションの自動デプロイ

> Hostの設定

Webアプリケーションの自動デプロイを有効にするには、対象の仮想ホストの設定が必要です。設定方法は、前述したHost要素のdeployOnStartup属性とautoDeploy属性です。

deployOnStartup属性とautoDeploy属性がtrueの場合、Tomcatは自動デプロイを実行します。新しいWebアプリケーションまたはWebアプリケーションの更新を検出すると、アプリケーションのデプロイ(または再デプロイ)が実行されます。

この2つの属性の主な違いは、deployOnStartupがtrueの場合、Tomcatは起動時にWebアプリケーションをチェックし、検出したすべてのWebアプリケーションを新しいアプリケーションとみなすことです。一方autoDeployがtrueの場合、Tomcatは実行中に定期的に新しいWebアプリケーションや更新をチェックします。これ以外の処理はおおよそ同じです。

deployOnStartup属性とautoDeploy属性の設定により、仮想ホストでのWebアプリケーション自動デプロイを有効にできます。実際には、自動デプロイは新しいWebアプリケーションや更新されたWebアプリケーションの有無をチェックする仕組みに依存しており、Host要素のappBase属性とxmlBase属性が、Webアプリケーションの更新をチェックするディレクトリを決めます。

appBase属性は、Webアプリケーションを配置するディレクトリを指定します。デフォルト値はwebappsで、相対パスでTomcatルート直下のwebappsフォルダを指します。

xmlBase属性は、WebアプリケーションのXML設定ファイルを配置するディレクトリを指定します。デフォルト値はconf/<engine_name>/<host_name>です。冒頭の設定例では、ホストlocalhostのxmlBaseのデフォルト値は$TOMCAT_HOME/conf/CoreEngine/localhostになります。

> Webアプリケーション更新のチェック

1つのWebアプリケーションには、XML設定ファイル、WARファイル、アプリケーションディレクトリ(Webアプリケーションのファイル群を含むディレクトリ)が含まれることがあります。XML設定ファイルはxmlBaseで指定されたディレクトリに置かれ、WARファイルとアプリケーションディレクトリはappBaseで指定されたディレクトリに置かれます。

Tomcatは次の順序でスキャンし、アプリケーションの更新をチェックします。

A、仮想ホストのxmlBaseで指定されたディレクトリ内のXML設定ファイルをスキャンする。

B、仮想ホストのappBaseで指定されたディレクトリ内のWARファイルをスキャンする。

C、仮想ホストのappBaseで指定されたディレクトリ内のアプリケーションディレクトリをスキャンする。

> <Context>要素の設定

Context要素で最も重要な属性はdocBaseとpathであり、reloadable属性もよく使われます。

docBase属性は、Webアプリケーションが使用するWARファイルのパスまたはアプリケーションディレクトリを指定します。注意点として、自動デプロイのシナリオでは、docBaseがappBaseディレクトリの外にある場合にのみ指定が必要です。docBaseで指定するWARファイルやアプリケーションディレクトリがappBase内にある場合、指定は不要です。TomcatがappBase内のWARファイルやアプリケーションディレクトリを自動でスキャンするため、あえて指定するとかえって問題を引き起こすことがあります。

path属性は、Webアプリケーションへアクセスするためのコンテキストパスを指定します。リクエストが届くと、TomcatはWebアプリケーションのpath属性とURIの一致度に基づいて、リクエストを処理するWebアプリケーションを選択します。

たとえば、Webアプリケーションapp1のpath属性が「/app1」、Webアプリケーションapp2のpath属性が「/app2」の場合、/app1/index.htmlへのリクエストはapp1が処理し、/app2/index.htmlへのリクエストはapp2が処理します。

あるContext要素のpath属性が「」の場合、そのContextは仮想ホストのデフォルトWebアプリケーションになります。リクエストのURIがどのpathとも一致しない場合、このデフォルトWebアプリケーションが処理を行います。

ただし、自動デプロイのシナリオではpath属性を指定できません。path属性は、設定ファイルのファイル名、WARファイルのファイル名、またはアプリケーションディレクトリの名前から自動的に導出されます。たとえばスキャン時にxmlBaseディレクトリ内のstore.xml、またはappBaseディレクトリ内のstore.warやstoreアプリケーションディレクトリが見つかった場合、そのWebアプリケーションのpath属性は「store」になります。名前がstoreではなくROOTの場合は、そのWebアプリケーションが仮想ホストのデフォルトWebアプリケーションとなり、path属性は「」と導出されます。

reloadable属性は、Tomcatが実行中にWEB-INF/classesディレクトリとWEB-INF/libディレクトリ内のクラスファイルの変更を監視するかどうかを指定します。trueの場合、クラスファイルの変更を検出するとWebアプリケーションの再ロードが実行されます。

開発環境ではreloadableをtrueにするとデバッグがしやすくなります。一方、本番環境でtrueにするとサーバーへ性能的な負荷がかかるため、reloadable属性のデフォルト値はfalseです。

自動デプロイの際、xmlBaseディレクトリ配下のXML設定ファイルstore.xmlに次のように記述する例を見てみましょう。

<Context docBase="/var/data/store.war" reloadable="true" />

この例では、docBaseはHostのappBaseディレクトリの外にあります。path属性は指定されていませんが、store.xmlというファイル名から自動的に「store」と導出されます。開発環境での利用を想定しているため、reloadable="true"としてデバッグしやすくしています。

> 自動デプロイの例

自動デプロイの最も典型的な例は、Tomcatインストール直後の状態です。$TOMCAT_HOME/webappsディレクトリの下に、次のようなフォルダが配置されています。

ROOT、docs、examples、host-manager、manager

Tomcatを起動した後、http://localhost:8080/ でアクセスすると、実際にはROOTに対応するWebアプリケーションへアクセスしています。

また、http://localhost:8080/docs とすればdocsアプリケーションへアクセスできます。同様に、examples、host-manager、managerといったWebアプリケーションにもアクセスできます。

(3)server.xmlでの静的デプロイ

自動デプロイ以外にも、server.xml内で<Context>要素を使ってWebアプリケーションを静的にデプロイすることができます。

静的デプロイと自動デプロイは共存できます。ただし実際の運用では、静的デプロイは推奨されません。server.xmlは動的に再ロードできないリソースであり、サーバー起動後にこのファイルを変更するためにはサーバーの再起動が必要になるからです。一方の自動デプロイは、Tomcatの実行中に定期的なスキャンによって実現されるため、再起動は不要です。

server.xml内でContext要素を使ってWebアプリケーションを設定する場合、Context要素はHost要素の中に配置します。例は次のとおりです。

<Context path="/wh" docBase="/srv/legacy/warehouse.war" reloadable="true" />

docBase:静的デプロイの場合、docBaseはappBaseディレクトリ内にあっても外にあっても問題ありません。この例では、docBaseはappBaseディレクトリの外にあります。

path:静的デプロイの場合はpath属性を明示的に指定できますが、依然として制約があります。自動デプロイが完全に無効(deployOnStartupとautoDeployがともにfalse)になっているか、docBaseがappBase内にない場合に限り、path属性を設定できます。この例ではdocBaseがappBase内にないため、path属性を設定できます。

主要コンポーネントの関連性

全体の関係

主要コンポーネント同士の関係は前節で断片的に述べましたが、ここで整理します。

Server要素は最上位に位置し、Tomcatコンテナ全体を表します。1つのServer要素には1つ以上のService要素を含められます。

ServiceはConnectorとEngineを包み込み、それらを組み合わせて外部にサービスを提供します。1つのServiceには複数のConnectorを置けますが、Engineは1つだけです。Connectorがリクエストを受け取り、Engineがリクエストを処理します。

Engine、Host、Contextはすべてコンテナであり、EngineはHostを含み、HostはContextを含みます。各HostコンポーネントはEngine内の1つの仮想ホストを表し、各Contextコンポーネントは特定のHost上で動作する1つのWebアプリケーションを表します。

リクエストの処理対象はどのように決まるのか

リクエストがTomcatサーバーへ送信されたとき、最終的にどのWebアプリケーションがそのリクエストを処理するのでしょうか。

(1)プロトコルとポート番号でServiceとEngineを選定する

Service内のConnectorコンポーネントは、特定のポートでリクエストを受け取ります。そのためTomcatの起動時、Serviceは特定のポートをリッスンします。冒頭の設定例では、CoreServiceというServiceが、9090番ポート(HTTPプロトコル)と8011番ポート(AJPプロトコル)をリッスンしています。

リクエストが届くと、Tomcatはプロトコルとポート番号に基づいて処理対象のServiceを選定します。Serviceが決まれば、そこで使われるEngineも自動的に決まります。

Server内に複数のServiceを設定することで、同じマシン上にデプロイされた異なるアプリケーションへ、異なるポート番号でアクセスできます。

(2)ドメイン名またはIPアドレスでHostを選定する

Serviceが決まると、TomcatはService内でドメイン名またはIPアドレスと一致する名前を持つHostを探し、そのHostにリクエストを処理させます。見つからない場合は、Engineで指定されたdefaultHostがリクエストを処理します。

冒頭の設定例では、Hostが1つしかない(name属性がlocalhostのHost)ため、そのService/Engine宛てのすべてのリクエストは、このHostが処理します。

(3)URIでContext(Webアプリケーション)を選定する

この点はContextの節で詳しく説明しました。Tomcatは、アプリケーションのpath属性とURIの一致度に基づいて、リクエストを処理するWebアプリケーションを選択します。ここでは繰り返しません。

(4)具体例

たとえば、http://localhost:9090/store/index.html というリクエストを考えます。まずプロトコルとポート番号(httpと9090)からServiceを選定します。次にホスト名(localhost)からHostを選定します。最後にURI(/store/index.html)からWebアプリケーションを選定します。

複数のServiceを設定する方法

Server内に複数のServiceを設定すると、異なるポート番号を使って、同じマシン上にデプロイした異なるWebアプリケーションへアクセスできます。

server.xmlで複数のServiceを設定する手順はきわめて簡単です。

(1)<Service>要素をコピーし、現在の<Service>要素の後ろに配置します。

(2)ポート番号を変更します。リッスンさせたいポート番号に合わせて<Connector>要素のport属性を変更します。そのポートが他のプロセスに使用されていないことを確認してください。使用されている場合、Tomcat起動時にエラーが発生し、そのポート経由でWebアプリケーションへアクセスできなくなります。

Windows 7を例にすると、次の方法でポートの占有状況を確認できます。netstat -aon | findstr "8081" を実行し、8081番ポートがPID 2064のプロセスに占有されていると分かったら、tasklist | findstr "2064" で、そのプロセスがFrameworkService.exe(McAfeeアンチウイルスのプロセス)であることを確認できます。

(3)ServiceとEngineのname属性を変更します。

(4)HostのappBase属性(例:deploy2)を変更します。

(5)Webアプリケーションは自動デプロイのままにします。

(6)デプロイしたいWebアプリケーション(WARファイルまたはアプリケーションディレクトリ)を新しいappBase配下へコピーします。

冒頭のserver.xmlを例に、複数のServiceを設定すると次のようになります。

<?xml version='1.0' encoding='utf-8'?>
<Server port="8006" shutdown="HALT">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserRegistry" 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 name="CoreService">
    <Connector protocol="HTTP/1.1" port="9090" connectionTimeout="20000" redirectPort="9443" />
    <Connector protocol="AJP/1.3" port="8011" redirectPort="9443" />
    <Engine name="CoreEngine" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserRegistry"/>
      </Realm>

      <Host name="localhost" appBase="/opt/project/deploy" unpackWARs="false" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="core_access_log." suffix=".log" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>

  <Service name="ExtService">
    <Connector protocol="HTTP/1.1" port="9092" connectionTimeout="20000" redirectPort="9443" />
    <Connector protocol="AJP/1.3" port="8012" redirectPort="9443" />
    <Engine name="ExtEngine" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserRegistry"/>
      </Realm>

      <Host name="localhost" appBase="/opt/project/deploy2" unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="ext_access_log." suffix=".log" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

元のdeployディレクトリ配下のdocsディレクトリをdeploy2ディレクトリへコピーすれば、次の2つのURLでdocsアプリケーションにアクセスできます。

http://localhost:9090/docs/

http://localhost:9092/docs/

その他のコンポーネント

Listener

<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

Listener(リスナー)として定義されたコンポーネントは、特定のイベントが発生したときに特定の処理を実行できます。監視対象となるイベントは、通常Tomcatの起動と停止です。

リスナーはServer、Engine、Host、Contextのいずれにも配置できます。この設定例では、6つのリスナーがすべてServer内に配置されています。実際、この設定例で定義されている6つのリスナーは、いずれもServerコンポーネント内にしか配置できません。リスナーは他のコンポーネントを内包することはできません。

リスナーで最も重要な属性はclassNameです。この属性はリスナーの具体的な実装クラスを指定し、そのクラスはorg.apache.catalina.LifecycleListenerインターフェースを実装していなければなりません。

設定例で定義されているリスナーを順に紹介します。

  • VersionLoggerListener:Tomcat起動時に、Tomcat、Java、OSに関する情報をログへ記録します。このリスナーは最初に設定しなければなりません。
  • AprLifecycleListener:Tomcat起動時にAPRライブラリの存在をチェックし、存在すればロードします。APRはApache Portable Runtime(Apacheポータブルランタイム)の略で、高い拡張性と性能、そしてネイティブなサーバーテクノロジーとの統合を実現します。
  • JasperListener:Webアプリケーションの起動前にJasperを初期化します。JasperはJSPエンジンであり、JVMが認識できないJSPファイルをJavaファイルへ解析し、さらにclassファイルへコンパイルしてJVMから利用できるようにします。
  • JreMemoryLeakPreventionListener:クラスローダーに起因するメモリリークの防止に関係します。
  • GlobalResourcesLifecycleListener:このリスナーを通じて、<GlobalNamingResources>タグ内で定義されたグローバルJNDIリソースを初期化します。このリスナーが無いと、どのグローバルリソースも利用できません。<GlobalNamingResources>については後述します。
  • ThreadLocalLeakPreventionListener:Webアプリケーションがthread-localに起因するメモリリークによって停止する際に、このリスナーがスレッドプール内のスレッドの更新をトリガーします。スレッドがタスクを実行し終えてスレッドプールへ戻されるとき、アクティブなスレッドが1つずつ更新されます。このリスナーが有効になるのは、Webアプリケーション(すなわちContext要素)のrenewThreadsWhenStoppingContext属性がtrueに設定されている場合だけです。

GlobalNamingResourcesとRealm

<Realm className="org.apache.catalina.realm.LockOutRealm">
  <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
         resourceName="UserRegistry"/>
</Realm>

Realmは「領域」や「ドメイン」と理解できます。Realmは、ユーザーのパスワードとWebアプリケーションの対応関係を提供し、ロールベースのセキュリティ管理を実現します。

この設定例では、Realmの設定にnameがUserRegistryのリソースを使用しています。このリソースはServer要素内のGlobalNamingResourcesで次のように定義されています。

<GlobalNamingResources>
  <Resource name="UserRegistry" 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>

GlobalNamingResources要素はグローバルリソースを定義します。上記の設定は、$TOMCAT_HOME/conf/tomcat-users.xmlを読み込むことによって実現されています。

Valve

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
       prefix="core_access_log." suffix=".log"
       pattern="%h %l %u %t &quot;%r&quot; %s %b" />

Valveは「バルブ(弁)」を意味し、Tomcatではリクエスト処理パイプライン上の1つのコンポーネントを表します。ValveはTomcatのコンテナ(Engine、Host、Context)に関連付けることができます。

Valveの種類によって特性は異なります。ここでは、設定例に登場するAccessLogValveを紹介します。

AccessLogValveは、自身が属するコンテナで処理されたすべてのリクエストをログへ記録します。この設定例ではValveがHost配下に配置されているため、このHostが処理したすべてのリクエストを記録できます。

AccessLogValveが記録するのはアクセスログであり、1日分のリクエストが1つのログファイルへ書き出されます。AccessLogValveはEngine、Host、Contextのいずれにも関連付けることができます。この設定例ではEngineが1つ、その配下にHostが1つ、さらにその配下にContextが1つのみの構成のため、AccessLogValveをどのコンテナに配置しても実質的な動作はほぼ同じです。

このAccessLogValveの各属性の意味は次のとおりです。

(1)className:Valveの種類を指定する最も重要な属性です。この設定例では、AccessLogValveであることを指定しています。

(2)directory:ログの保存先ディレクトリを指定します。この設定例では、$TOMCAT_HOME/logsディレクトリ配下にログが保存されます。

(3)prefix:ログファイル名のプレフィックスを指定します。

(4)suffix:ログファイル名のサフィックスを指定します。directory、prefix、suffixの設定により、$TOMCAT_HOME/logsディレクトリ配下にログファイルが作成されます。

(5)pattern:ログの記録形式を指定します。設定例で使われている各項目の意味は次のとおりです。

  • %h:リモートホスト名またはIPアドレスです。nginxなどのリバースプロキシがリクエストを振り分けている場合はそのプロキシのホスト名/IPアドレスを表し、そうでない場合はクライアントの情報を表します。以降の「リモート」も同じ意味です。
  • %l:リモート論理ユーザー名です。通常は「-」となり、無視して構いません。
  • %u:認証済みのリモートユーザー名です。認証されていない場合は「-」となります。
  • %t:アクセスした時刻です。
  • %r:リクエストの最初の行です。リクエストメソッド(GETやPOSTなど)、URI、プロトコルが記録されます。
  • %s:レスポンスのステータスコードです。200や404などが記録されます。
  • %b:レスポンスのデータ量です。リクエストヘッダは含まれません。0の場合は「-」となります。

patternの設定では上記以外にも、%D(リクエスト処理時間。単位はミリ秒)がよく使われます。リクエスト処理速度の統計分析に非常に役立ちます。

タグ: Tomcat server.xml Java configuration

9月10日 07:01 投稿