|
このドキュメントでは、Tomcat を有名なオープンソースの Web サーバ である Apache に接続する方法について説明します。これは、元々 Gal Shachor が書いたTomcat: A Minimalistic User's Guideの一部でしたが、 構成上の理由により分割しました。このドキュメントは、 作業中であると見なすべきです。Tomcat のソースツリーは 日常的に変更されているので、この情報は古くなっているか もしれません。現時点で最も信頼できるリファレンスは、ソースコードだけです。
他にも重要なドキュメントがあります。
連携の必要性
Tomcat ユーザーズガイド 内で述べているように、Tomcat は現在 3 種類の実行方式をサポートしています。 Tomcat は、必要であれば静的なドキュメントと動的なドキュメントの両方を完全に提供することもできるのですが、 そうしない方がよいいくつかの理由があります。 Apache Web サーバと比較すると、以下のような点が問題になります。
1. 静的なページに関して Tomcat は Apache ほど速くありません。
2. Tomcat は、Apache ほど 細かな設定ができません。
3. Tomcat は、Apache ほど 頑強ではありません。
4. Tomcat は、 Apache のモジュール(例 Perl, PHP, その他)でしか提供していない機能に対する多くのサイトの要望に答えられないかもしれません。これらの理由から、静的なコンテンツの提供には、Apache のように世界中のサイトが使っている実用に耐えられる Web サーバを使用して、さらにTomcat を Servlet/JSP のアド・オンとして使うことを推奨します。
どのように協調して動作するのですか?
Nutshell によると、Web サーバは常にリクエストを待っています。 サーバは、リクエストが届いた時に、リクエストを処理するために必要な様々な事を、必要なコンテンツを提供することで処理します。 Tomcat を追加すると、このふるまいのいくつかが変更されるかもしれません。 Web サーバは以下の事を行う必要があります。
- 最初のリクエストを処理する前に, Apache は Web サーバアダプタ (Tomcat が Apache と通信する手段) ライブラリをロードし初期化する必要があります。
- リクエストが届いた時には、Apache はそれが Servlet に属するものか を確かめる必要があります。もしそうなら、アダプタがリクエストを受け取って、 処理するようにする必要があります。
私たちは、画像や HTML ドキュメントのような静的コンテンツは Apache が処理して、 動的コンテンツへのリクエストはすべて Tomcat に転送するようにすべきです。 より具体的に言うと、私たちは以下の質問に答える必要があります。
1. どのようにして Apache は、 どのタイプのリクエストが Tomcat に転送されるべきだと知りますか?
2. どのようにして Apache は、それらのリクエストを Tomcat に転送しますか?
3. どのようにして Tomcat は、 それらのリクエストを受け付け処理しますか?私たちの説明の大半は 1 と 2 に関して費やされるでしょう。 3 は簡単ですね!
何が必要ですか?
上記 3 つの質問に対する答えです!
1. Apache の httpd.conf ファイルの修正。
2. Web サーバアダプタのインストール。
3. Tomcat の server.xml ファイルの修正。Tomcat と Apache を統合しようとする前に、 それぞれの設定の修正は楽にできると仮定します。 私たちは Tomcat/Apache/Servlet の専門用語を、 既にそれぞれのユーザガイドで学んで来たものとして、特に説明をしないで使用します。 Tomcat のセットアップに関する詳細は Tomcat ユーザーズガイド 内で見つけられます。Apache に関する設定情報は Apache ユーザーズガイド 内で見つけられます。
このドキュメントでは、次の例を常に参照することになりますが、この例を実行するためには最初にApacheをインストールしておく必要があります。
バーチャルホストを使わない例
1. すべての http://localhost/ を含むリクエストは "rootExample" コンテキストへ送られます。
2. すべての http://localhost/subdirExample/ を含むリクエストは "slifkaExample" コンテキストへ送られます。バーチャルホストを使う例
3. すべての http://virtualhost/ を含むリクエストは "vhostExample" コンテキストへ送られます。
4. すべての http://virtualhost/vhostSubdir/ を含むリクエストは "vhostSubdir" コンテキストへ送られます。
これらの設定をすべておこなえば、Servlet は適切にマウントされるでしょう。 特別なコンテキストである WEB-INF/web.xml ファイルで登録した Servlet にアクセスするためには、 URL "/servlet/登録されたServlet名" を追加するように設定します。たとえば (2) において、このコンテキストのための web.xml の一部を以下に示します。
<servlet>
<servlet-name>SlifkaWorld</servlet-name>
<servlet-class>foo.bar.baz.SomeClass</servlet-class>
<init-param>
<param-name>someParameter</param-name>
<param-value>A value</param-value>
</init-param>
</servlet>
このServletにアクセスするためには、 http://localhost/subdirExample/servlet/SlifkaWorld というリクエストをします。
web.xml、コンテキスト、Servlet、Webアプリケーションについてよくわからない場合には、 おそらく Tomcat ユーザーズガイド を通して読んだことがないのでしょう。 ぜひ読んでください!
Tomcat の設定は、他の 2 つの項目とは独立して行うことができます。 ここでは、あなたがユーザーズガイド の説明を理解していて、Tomcatを起動して、 スタンドアローンモード で実行した事があると仮定しています。
コンテキストの設定
まず最初に、Tomcat の server.xml に例のコンテキストを明示的に設定しましょう。 それぞれの設定の断片の前の数字は、前途の実行例を指します。
1. <Context path="/"
docBase="webapps/rootExample"/>
2. <Context path="/slifkaExample"
docBase="webapps/slifkaExample"/>例 (3) は、server.xml の <Host> 要素内になければいけません。 なぜなら、同じパス属性を持つ <Context> が存在しているからです。 例 (1) は、例 (3) と同じように "/" を指しています。 例 (4) も同じように <Host> 要素内に置きます。なぜなら、 リクエストでバーチャルホストを指定したときに限りアクセスできるようにしたいからです。 <Host> 要素に関するより詳しい情報は、ユーザーズガイドの server.xml 節や以下のバーチャルホストの節を参照してください。
ここを通り過ぎる前に、3 と 4 が抜けているのを思い出してください!
<Host name=" 完全修飾名(FQDN)もしくはバーチャルホストの IP アドレス ">
3. <Context path="/"
docBase="webapps/vhostExample"/>
4. <Context path="/vhostSubdir"
docBase="webapps/vhostSubdir"/>
</Host>server.xml を適切に修正した後には、 Tomcat を再起動することを忘れないでください。
動作確認
今、私達は何をしているのでしょうか? 今までユーザーズガイドでしっかり学んできた通常のTomcat のインストールとは、かなり違っているでしょう。 Tomcat はすべてのコンテキストの静的、および動的なドキュメントの両方を提供しているはずです。 どのコンテキストがどのリクエストを提供しているかを確かめる簡単な方法は、 標準出力や標準エラー出力、またはログファイルに出力される Tomcat のログを見ることです。
AJP コネクタ
この節を終える前に、もう一つTomcatのserver.xml のAJP <Connector> 要素について説明しておかなければいけません。 これは Tomcat が Apache と通信するための仕組みです。
<!-- Apache AJP12 をサポートしています。これは Tomcat を終了するためにも使います。 -->
<Connector className="org.apache.tomcat.service.PoolTcpConnector">
<Parameter name="handler"
value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
<Parameter name="port"
value="8007"/>
</Connector>実際にそのポートで待機している事を確かめるためには、 Telnet をするか、HTTP リクエストを送信してみましょう。 Ajp12ConnectionHandler は、例外を発生するので(tomcat ログファイルで確認できます)、待機している事が分かります。 Web サーバアダプタでは、これがTomcat 側で今本当に知る必要がある事のすべてです。
Tomcat は Ajp13ConnectionHandler 経由で AJP v1.3 もサポートしています。 これについては、後から mod_jk と mod_jserv について説明する時に述べます。
Apache を Tomcat と統合する次のステップは Web サーバアダプタのインストールです。 これは Tomcat と Apache の間の情報を受け渡しする小さなソフトウェアです。 これは実際 Apache の設定に入るというわけではありませんし、 Tomcat の設定に入るというわけでもありません。 しかし一緒に動作するには両方が必要なのです。
Web サーバアダプタは、上で出てきた質問 2 「どのようにして Apache は、それらのリクエストを Tomcat に転送しますか?」 への回答です。
mod_jk と mod_jserv
現在 jk と JServの2つのアダプタが利用できます。
「mod_jk の利用方法」から引用します。
mod_jkは、以前の mod_jserv を置き換えるものです。 これは Tomcat への接続を橋渡しする Tomcat-Apache プラグインです。 幸運なことに、これを使うことで、すべての人にとって簡単になります。 利点をいくつか挙げます。
- mod_jserv は Tomcat には必要がない JServ 独自の機能をサポートしていたために複雑すぎました。
- mod_jserv は Apache しかサポートしていません。 一方 Tomcat は jk ライブラリという名称の互換層を介して、多くの Web サーバをサポートしています。 異なる 2 つの動作モードをサポートすると、サポートや、ドキュメント、 バグ修正などの点で問題が起りやすくなりますが、mod_jk はこの問題を解決します。
- jk ライブラリによる階層型アプローチによって、 Apache 1.3.x と Apache 2.xx のサポートが簡単になります。
- mod_jserv は AJP v1.2 しかサポートしません。 JServ の機能は完成していて、バグ修正以外の拡張はおこなわれません。
- mod_jk は以下をサポートします。
- AJP v1.3 - Apache とTomcat 間の TCP 接続を再利用するのでより速くなります。
- JNI - Apache 2.0 のようなマルチスレッド対応のサーバを利用していれば最速です。
アダプタの入手元
Linux と Win32 のバイナリは、 Tomcat 配布ファイルの bin ディレクトリにあります。 Linux では、JServ は mod_jserv.so として、 Jk は mod_jk.so として利用できます。 Win32 では、JServ は ApacheModuleJServ.dll として、Jkは mod_jk.dll として利用できます。
UNIX では、 JServ と Jk はソースから構築しないといけません。 ソースは、Tomcat ソース配布の一部です。JServ のソースは src/native/apache/jServ のディレクトリにあります。ここには UNIX と Win32 用の make ファイルがあります。Jk のソースは src/native/jk とApache のバージョンによって src/native/apache1.3 もしくは src/native/apache2.0 にあります。FreeBSD、Linux、Netware、 Win32(Visual C++ 6 プロジェクトファイルとして)用の Jkのmake ファイルは、 apache1.3 と apache2.0 ディレクトリにあります。
アダプタの構築方法
JServ の make ファイルの中には、簡単な説明が書かれています。 より詳しい情報については、ユーザーズガイド に書かれています。Win32 と *nix における mod_jk の構築手順を簡単に下に示します。 これはすべての環境における完全な構築過程ではなく、素早く開始するためのものです。
Win32 (mod_jk の利用方法からの抜粋)の場合
リダイレクタはVisual C++ Ver.6.0を使って開発されたので、カスタムビルドしたい場合には、あらかじめこの環境を用意しておく必要があります。 以下の順序で実行します。
- (上記の)Apache のソースディレクトリに移動します。
- APACHE1_HOME 環境変数が Apache がインストールされている場所を指すように設定します。
- 以下のコマンドを実行します。
MSDEV mod_jk.dsp /MAKE ALL
注意: msdev があなたのパスに存在しない場合には、msdev.exe のフルパスを入力してください。 また、 ApacheCore.lib が APACHE1_HOME\src\CoreD の中に存在して、 APACHE1_HOME\src\CoreRディレクトリの前にリンクされる必要があります。 さらに、これらのライブラリを作成するためには、 Apache のソースをビルドする必要があります。- mod_jk.dll を Apache の modules ディレクトリにコピーします。
この方法で、リダイレクタプラグイン (mod_jk) のリリース版とデバッグ版の両方を作成できます。 他に msdev の mod_jk.dsp をオープンして、ビルドメニューを使って作成する方法があります。
UNIX の場合
- (上記の)Apache のソースディレクトリに移動します。
- $APACHE_HOME 環境変数を Apache ソースツリーの一番上に設定します。
- 以下のコマンドを実行します。
./build.sh以上です!
(訳注: build.sh は、Tomcat3.2.2 では存在しないので、替わりに Makefile.linux 等を使用します。)
設定における注意
それぞれのアダプタを有効にするためには、異なる Apache の指示子を使用します。 概念的には Apache の指示子を追加するのですが、 どのアダプタを選択するかによって異なります。 この後の「Apache の設定」の節で、さらに両アダプタについて説明します。
すでに、私達は質問 (2) と (3)に答えました。 これで質問 (1) - Apache それ自身へ突入する準備が整いました。 どのようにしてアダプタをロードして初期化するか、 リクエストがどのアダプタが処理してTomcatへ転送するかについてApache に指定する必要があります。 それらのリクエストは設定に依存しています。 Tomcat が大部分の仕事をすることを考えると (驚きです!) 、この部分は前の 2 つと同じくらい、驚くほど簡単です。
Tomcat は、開始時に毎回、コンテキストをロードした後に(server.xml に定義されたものと $TOMCAT_HOME/webapps から自動的にロードされたものの両方)、 いくつかのファイルを自動的に生成します。その 2 つは、以下のファイルです。
これらの2つのファイルは、私達が正に望むこと - Apache(Tomcat) が静的な(さらに動的な)コンテンツを提供するために必要な指示子を Apache の httpd.conf ファイルに追加すること - をしてくれます。 この後の節でそれぞれのファイルについて調べます。多くの人にとっては、 使用するアダプタに応じて、それらのファイルの一つを直接 httpd.conf にインクルードするだけで十分でしょう。たとえば、mod_jk(お勧めです!) を使うなら、以下を追加します。
include /tomcat/conf/mod_jk.conf-auto
もちろん /tomcat の個所は Tomcatをインストールしたディレクトリに置き換えてください。 注意: これらのファイルは Tomcat を起動する度に生成されます。 Tomcat の設定変更がそれらのインクルードしているファイルに影響するときは 必ずApache を再起動してください。このファイルをカスタマイズする場合には、再起動時に上書きされるので、どこか他に移してください。
mod_jk.conf-auto
まず、mod_jk.conf-auto のコメントを参照してください。 詳細はmod_jk の使い方 にあります。
tomcat-apache.conf
mod_jk ファイルほど丁寧に書かれていないので、 読み通すためにはちょっとしたコツが必要です。 以下に、実行例に含まれる server.xml から生成された .conf ファイルの要約バージョンがあります。 説明しやすくするために、コメントを直接追加して、書式を見易くしてあります。
はじめる前に、広く使われているJServの指示子である「ApJServMound」について知らなくてはいけません。 ApJServMount は以下のようなシンタックスを持っています。
ApJServMount <URI> <Tomcat が処理する場所やコンテキストの URI 書式(相対、または絶対)>
英語では、これは「<URI> で始まるすべてのリクエストは、 実行するために<Tomcat が処理する場所やコンテキスト> へ渡されるべき」 といいます。まだ良く分からなくても気にしないで下さい。 以下に例がありますから!
このファイルは自動生成されたものをほんの少し修正してあります。 なぜなら、自動生成されたファイルは完全に望む事を満たしてるわけではありませんし、 コメントもないですから(笑) しかしほとんど同じです! これまで得られた知識を使えば、それほど難しくはないはずです。 では以下に示します。
静的コンテンツを Apache が提供する Apache-Tomcat の設定 ####################################################### # # JServ 設定の開始 # # Step (1) - このサンプルファイルに続く説明を参照 LoadModule jserv_module libexec/mod_jserv.so <IfModule mod_jserv.c># Step (2) - このサンプルファイルに続く説明を参照 ApJServManual on ApJServSecretKey DISABLED ApJServMountCopy on ApJServLogLevel notice# Step (3) - このサンプルファイルに続く説明を参照 ApJServDefaultProtocol ajpv12 ApJServDefaultPort 8007 # この最後の行を手で追加 ApJServDefaultHost localhost# # JServ 設定の終了 # ######################################################## 以下の 2 行は JSP タイプを Apache に登録し、 # すべての JSP リクエストを jserv-servlet ハンドラが # 処理するように支持しています。 AddType text/jsp .jsp AddHandler jserv-servlet .jsp# 変更前: ApJServMount /servlet /ROOT # 理由: すべての /servlet へのリクエストが Tomcat の # "/rootExample" コンテキストへ送られる事を明示的に # 指定したかったので変更しました。より詳しくは上記の # 例 (1)を参照して下さい。 ApJServMount /servlet /rootExample####################################################### # # Step (4) - 例 (1) 設定の開始 ## Step (4a) # 変更前: Alias /rootExample "/home/rslifka/tomcat/webapps/rootExample" # 理由: なぜこれを取り除いたのでしょうか? えぇ、これがあれば # http://localhost/rootExampleへのリクエストは正しい静的な # ドキュメントを提供します。不適切なことに、私達のアプリケーションが # /rootExample の下でなくサーバのルートにあることを望んだのです。 # # The DocumentRoot should be set instead. # DocumentRoot はその代わりにセットされるべきです。DocumentRoot /home/rslifka/tomcat/webapps/rootExample# Step (4b) # 理由: 標準の Apache の設定のように、リクエストがどのように # 処理されるかの特性を設定しています。これ以上を望むなら、Apache の # より詳細なドキュメントを参照して下さい(笑)。この特別な設定はディレ # クトリの一覧を有効なままにしておきます。たいていの人は無効にしてい # ますが。そうするには、<Directory> 属性の真中のコメントアウトされた # 行を使います。 <Directory "/home/rslifka/tomcat/webapps/rootExample"> Options Indexes FollowSymLinks # Options -Indexes </Directory># Step 4(c) # 変更前: ApJServMount /rootExample/servlet /rootExample # 理由: なぜこれを取り除いたのでしょうか?それはこのコンテキストの設定の前に # 最初の ApJServMount でより上に再マップしたからです。 ## Step 4(d) # 理由: Servlet仕様によると、すべての宝(web.xml, その他) があるので # WEB-INF の下は何も見えるべきではありません。アプリケーション階層に # 関するより詳しい情報はユーザーズガイドかServlet仕様を見てください。 <Location "/home/rslifka/tomcat/webapps/rootExample/WEB-INF/"> AllowOverride None deny from all </Location># # 例 (1) 設定の終了 # ############################################################################################################## # # Step (5) - 例 (2) 設定の開始 #Alias /subdirExample /home/rslifka/tomcat/webapps/slifkaExample ApJServMount /subdirExample/servlet /slifkaExample<Location "/home/rslifka/tomcat/webapps/slifkaExample/WEB-INF/"> AllowOverride None deny from all </Location><Directory "/home/rslifka/tomcat/webapps/slifkaExample"> Options Indexes FollowSymLinks </Directory># # 例 (2) 設定の終了 # #######################################################</IfModule>上記の"ApJServ" で始まる指示子以外のすべての指示子は、Apache ユーザーズガイド で詳しく記述されています。私達の説明が少ないと思った場合には、 欲しい情報をそこで探してください。
以下で,それぞれのコメントされたステップについて更に詳細を示します。
1. Apache に共有オブジェクト(NT の世界では dll) をロードするように指示します。
mod_jserv.c のモジュールのロードが成功した場合には、(1a) 残りの設定をおこなうことができます。
2. このステップでは、いくつかの JServ の内部的なパラメータを順番に設定します。
- JServ が Tomcat プロセスを開始しないように指示します。 Tomcat の自動起動はまだ実装されていません。
- Apache と Tomcat 間の秘密キーのチェレンジ/レスポンスを無効にします。 秘密キーに関してもまだ実装されていません。
- バーチャルホストの場合には、JServ がベースサーバマウントポイント(次節を参照)をコピーするように指示します。
- JServ が notice ログレベルを利用するように指示します。 他のログレベルには emerg, alert, crit, error, warn, info, debug があります。
3. このステップでは JServ のデフォルトの通信パラメータを設定します。
デフォルトで使われているプロトコルは ajpv12(これとは干渉しません)で Tomcat プロセスは同じマシンの 8007 番ポートで待機している事を示しています。 Apache で使われているマシンと別のマシンで Tomcat を動作させているなら、 ApJServDefaultHost も更新しなければいけません。もしくはマウントするコンテキスト(次を参照)で完全 URL を使わなければいけません。 Tomcat のコネクタを 8007 番以外のポートを使うように設定しているのなら、 ApJServDefaultPort も更新しなければいけません。もしくはマウントするコンテキストで完全 URL を使わなければいけません。
4. 例 (1)のコンテキストを Apache に "登録" (他に良い言葉がありません)するステップです。
例の中でほとんどすべてが説明されています。しかし知っておくべき事がまだいくつかあります。 まず最初に、Web(例: http://localhost/とhttp://localhost/myApp) サーバのルートにマウントされたコンテキストは、それ以外のものより、少し多くの仕事が必要だと分かるはずです。 第 2 に、自動生成のために何も必要ありません。 これは素晴らしい機能であり、多くの所で、多くの場合で動作します。 それでもまだ、複雑な 2 つのソフトウェアを設定するためには、 おそらくすべての意味やなぜ、どのようにそれらが動作するかに熟知している必要があります! Tomcatは、Apacheにコンテキストを "登録する" 方法を知ることができないので、予測するためにベストを尽くします。
5. 例 (2) のコンテキストを Apache へ登録するステップです。
例 (1) と例 (2) の設定の間には 2 つの違いがあります。 最初に、DocumentRoot はすでに定義され、rootExample コンテンツ(例 (1)) にマウントされているので、Apache に静的ドキュメントをどのように提供するかを指示するためにAlias パラメータを使います。 次に、ApJServMount 指示子をコンテキストのあるパスを反映するために修正します(/subdirExample)。
設定は完璧です! あとは、Apacheを再起動するだけです。あなたはガスで料理でもしてください。
時々、異なるコンテキストを異なる JVM によって処理する方が役に立つことがあります。 たとえば、以下のような場合です。
Tomcat の設定
ここで Tomcat の設定に戻らなければいけません。 最初に、" 複数の JVM " なので、2 つの別々の Tomcat インスタンスを動かす必要があります。 もちろん、それぞれの Tomcat インスタンスは別々のポートで Web アダプタコネクタを待機させる必要があります。 AJP 節の server.xml の以下の断片を覚えているでしょう。
<!-- Apache AJP12 をサポートしています。これは Tomcat を終了するためにも使われます。 -->
<Connector className="org.apache.tomcat.service.PoolTcpConnector">
<Parameter name="handler"
value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
<Parameter name="port"
value="8007"/>
</Connector>ここでのキーポイントは、それぞれの "port" パラメータの "value" 属性は違った値でなければならないということです。 それらを同じにしてしまうと、例 (1)と 例 (2)を同じ Tomcat のインスタンスで実行しようとします。 例 (1) のポートは 8007 番で 例 (2) のポートは 8009 番です。 それらはどちらも localhost で動作しています。
注意: 複数の Tomcat インスタンスを実行するためには、他も変更しなければいけません(たとえば、違ったログディレクトリを指定するなど)。 それらの変更の詳しい情報についてはユーザーズガイドで解説しています。
Apache の設定
私達は .conf ファイルの(少なくともこの例に対して)重要でない部分については省略してきました。 コンテキストに対応する Tomcat プロセスを見つける方法をWeb サーバアダプタに指定する時には、あなたが変更しなければならない変更点は、少し構成に依存するようになります。
各コンテキストごとにJVMを用いるApache-Tomcatの設定 [ 省略! ] # 例 (1) のマウント ApJServMount /servlet ajpv12://localhost:8007/rootExample # 例 (2) のマウント ApJServMount /subdirExample/servlet ajpv12://localhost:8009/slifkaExample[ 省略! ]複数のインスタンスを Apache と統合するためのキーポイントは ApJServMount 指示子を使ってマウントするときに完全 URL を指定する事だと気づくでしょう。 これが Tomcat プロセスがそれぞれ別のポートで待機している事を JServ に伝える事を可能にする方法です。 Tomcat インスタンスが別々のマシンで動いてる場合には、 ApJServMount 指示子の "localhost" を適切なマシン名に変更すればいいでしょう。
注意: $TOMCAT_HOME/conf/tomcat-apache.conf ファイルは Tomcat を再起動する度に上書きされます。 この設定にはカスタマイズしたtomcat.conf が必要です。 変更を作成してから、自動生成されたファイルをインクルードする事は *悪い考え* です。 あなたの変更は Tomcat の再起動の度に上書きされるからです。
以前に <VirtualHost> エントリで正しく設定された Apache を見ています(上のパートで論じました)。 Tomcat でバーチャルホストを実現するのも難しくありません。 これを実現するためには、2つの方法があります。
最初の方法で Apache と Tomcat を設定するためには、それぞれのホストにおいて Apache と Tomcat が通信するために異なったポート番号を設定する必要があります。 ここにいくつかの Apache の(mod_jserv を使用する)設定を示します。
[ 省略! ] # 例 (3) のバーチャルホストをマウント <VirtualHost 9.148.16.139> ServerName www.virtualhost.com DocumentRoot path-to-your-docbase ApJServMount /servlet ajpv12://localhost:8007/vhostExample </VirtualHost> # 例 (4) のバーチャルホストをマウント <VirtualHost 9.148.16.139> ServerName www.virtualhost.com ApJServMount /servlet ajpv12://localhost:8009/examples DocumentRoot path-to-your-docbase </VirtualHost> [ 省略! ] |
注意: Apacheに静的なファイルをどこから提供するかを伝えるために DocumentRoot を設定すると覚えておいてください。 私達の mod_jserv と mod_jk の例では、DocumentRoot は既に定義されていたので、 Alias を指定するだけでした。 ApJServMount は DocumentRoot から相対的であることは、覚えておいてください。 DocumentRoot や Alias って何だろう? と思ったならば、 Apache ユーザーズガイド を見ましょう!
上の例から分かるのは、バーチャルホスト環境で Tomcat を使う場合は、 Apache に関しては違いがないという事です。 もちろん、適切に <VirtualHost> エントリを設定する必要はありますが、 それ以外には大きな違いはありません。それぞれのバーチャルホストエントリ内で、コンテキスト依存の情報を普通に指定します。 実際にそのとおりです。
これは上記の 2 番目の方法を使ったバーチャルホストの設定例です。
[ 省略! ] # 最低限のバーチャルホスト設定 <VirtualHost 192.168.0.1> ServerName host1 DocumentRoot /web/host1/html ApJServMount /servlet /ROOT <Directory "/web/host1/html/WEB-INF"> Options None Deny from all </Directory> </VirtualHost> <VirtualHost 192.168.0.1> ServerName host2 DocumentRoot /web/host2/html ApJServMount /servlet /ROOT <Directory "/web/host2/html/WEB-INF"> Options None Deny from all </Directory> </VirtualHost> [ 省略 ] |
これにより host1 と host2 の 2 つのバーチャルホストを作成します。 両方とも同じ IP アドレス - 192.168.0.1 で動作します。 "/servlet" で始まるパスのすべてのリクエストは Tomcat が処理するために渡されます。 もちろん JSP リクエストは、前述の AddType や AddHandler 指示子を追加する事により提供されます。
次に、Tomcat の server.xml ファイルを設定する必要があります。
[ 省略! ] # 最低限のバーチャルホスト設定 <VirtualHost 192.168.0.1> ServerName host1 DocumentRoot /web/host1/html ApJServMount /servlet /ROOT <Directory "/web/host1/html/WEB-INF"> Options None Deny from all </Directory> </VirtualHost> <VirtualHost 192.168.0.1> ServerName host2 DocumentRoot /web/host2/html ApJServMount /servlet /ROOT <Directory "/web/host2/html/WEB-INF"> Options None Deny from all </Directory> </VirtualHost> [ 省略! ] |
(訳注: これは server.xml じゃなく httpd.conf の例になってしまってます。間違えてコピーペーストされているようです。)
これで終わりです! それぞれのバーチャルホストのための WEB-INF/classes ディレクトリに Servlet を置いてから、Tomcat と Apache を再起動すれば、あなたは離れてもかまいません。 うまくいかない場合には、一般的な問題の節を確認してください。
この節は Tomcat-Apache に関するすべてのトラブルのためのワンストップショップではありません。 しかし、一般的な悩みの種の対策は、多くの Tomcat の初心者の役に立つでしょう。 ユーザーズガイドの ヘルプ節に追加のリンクがあります。
多くのユーザが気づかないことの一つですが、ログファイル中には非常に多くの情報が見つかります! まず最初に、$TOMCAT_HOME/logs ディレクトリ、もしくは設定した別のところにある tomcat.log ファイルを見ましょう。 より詳しい情報が必要ならば、ユーザーズガイドで より詳しいログを得るための server.xml の編集方法を調べましょう。
In addition, the web server adapter has a log file as well. It's usually <adapter_name>.log (e.g. mod_jserv.log).
さらに、Web サーバアダプタにも同じようにログファイルがあります。 それは普通 <アダプタ名>.log (例: mod_jserv.log) と言う名前です。
http://webserver:8007/にアクセスすると HTTP 500 エラーが発生します
この問題が発生した場合には、tomcat.log ファイル内の次のように始まるスタックトレースを見るべきです。
デフォルトで Tomcat は AJP 接続を 8007 番のポートで待機しています。 AJP は Web サーバと Tomcat が通信するためのプロトコルですが、 Tomcat とブラウザが通信するプロトコルではありません。 この場合に限らなくても、多くの初めてのユーザは、 これが Tomcat のインストールや Tomcat-Apache の統合をテストする方法だと思っていますが、それは正しくありません。
Tomcat が動作中にApache を起動できません
これはTomcat がすでに他の何か - たいていは Apache か他の Tomcat インスタンス - が使用しているポートを使用しようとしている事を意味しています。 デフォルトでは、 Tomcat は HTTP サーバを 8080のポートで実行するように設定されます。 提供されている server.xml ファイルを調べてみれば、以下のような要素が見つかるでしょう。
<!-- Normal HTTP -->
<Connector className="org.apache.tomcat.service.PoolTcpConnector">
<Parameter name="handler"
value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
<Parameter name="port"
value="8080"/>
</Connector>これを無効にするためには、<Connector> 要素を正しくコメントアウトして下さい。 もしくは、Apache と衝突しないポート番号に正しく変更して下さい。 Tomcat の HTTP サーバを使用しない場合には、このドキュメントを読んでるならおそらくそうでしょうが、Tomcat の HTTP サーバを無効にして下さい。
Apache / JServ を実行している場合には、JServ は 同様にポート 8007 番で Tomcat と衝突するでしょう。
Apache/JServ と Apache/Tomcatの両方を同じマシン上で実行できますか?
確かにできますが、mod_jk でなく mod_jserv を使う必要があります。 Tomcat 3.2b2 では、mod_jserv.so は Apache/JServ が使用しているものと同じです。 Apache/JServ を Tomcat と違ったポートで実行する必要があります。 そうすれば Apache の httpd.conf のApJServMount 指示子で適切なポートを指定する事により、 どのServletエンジン、コンテナがどのリクエストを処理するかを制御する事ができます。
<Directory> や <Location> 指示子が無視されているようです
Apache はマウント下へのすべてのリクエストを Tomcat へ転送します。 以下のような最上位レベルの httpd.conf だったとします。 あなたは「すべての JSP とServletのリクエストを Tomcat に転送しよう」と考えているかもしれません。 しかし、Apache は「すべてを Tomcat に転送しよう」と考えています。
間違った Tomcat-Apache の設定 [ 省略! ]# うっ! すべてを Tomcat へ転送してしまってる… ApJServMount / ajpv12://myTomcatHost:1234/blah# ディレクトリ内の一覧を表示しない <Directory "/home/myApp"> AllowOverride AuthConfig Options -Indexes </Directory> # WEB-INF はアクセス不可能に <Location "/home/myApp/WEB-INF/"> AllowOverride None deny from all </Location> [ 省略! ]
ここで起こっているのは、最初の ApJServMount は「ルート '/' 以下のすべてのリクエストは Tomcat プロセス/パスで処理するために転送するべきである。」と言っている事です。 この結果、静的なドキュメントも同様に転送されてしまいます。 これは私達が望む事ではありません。 もし上の設定ファイルを '修正' するように言われたなら、ApJServMount の後ろの '/' を "/servlet" へ変更します。 すでにあなたはこのドキュメントの前の方ですべての JSP リクエストを jserv Servletハンドラへ転送するように定義しているでしょう(Apache-mod_jserv 設定の節を見てください)。mod_ssl - Internet Explorer を使っていると時々ページの読み込みが終了しないことがあります
Tomcat はTransfer-Encoding: を使用して、データをブラウザに返信します。 これは Internet Explorer で SSL を使っているときに問題を引き起こします。 解決策は、返すファイルの最初の行を空行にしないようにする事です。
mod_ssl - getScheme() がいつも HTTP を返します!
mod_jserv で使われているプロトコルでは、ページが HTTPとHTTPSのどちらを使ってリクエストされたかを確認する事ができません。 もちろん、Apache/JServ ではできます。しかし、それはハックです(リクエストがポート 443 かをチェックしてるだけです)。 解決策は、あなた自身がポート 443 かどうかをチェックするか、mod_jk と ajpv13 プロトコルへアップグレードするかです。 これの別の兆候は https://yourserver.com/ よりむしろ http://yourserver.com:443 へリダイレクトされているリクエストを探す事です。
Apache/JServ JSSI から Apache/Tomcat への移行
Tomcat は JSSI をサポートしません。誰かが JSSI を処理するインターセプタを作るまで、 一番簡単な方法は .jhtml ファイルを .jsp ファイルへ変換する事です。 ちょうど以下のものを、
<servlet name=myServlet>
<param name=aParam value=aValue>
</servlet>以下のように置き替えることができます。
<jsp:include page="/servlet/myServlet" flush="true" >
<jsp:param name="aParam" value="aValue" />
</jsp:include>mod_rewrite - Apache/JServ では正常に動いてました。どうすればいいのですか?
Tomcat はServlet仕様 v2.2 を実装していますが、 JServではバージョン 2.1 を実装していました。 新しいバージョンでは、URL(ユーザがリクエストするもの)からファイル名(ユーザが得るもの)にマッピングする際に、より厳しい制限があります。 特に、以下を要求します。
request URI = context path + servlet path + path info
これは mod_rewrite では簡単にできる任意のマッピングが、Servlet仕様を破らずには機能しない事を意味します。 一つの解決策はリクエストへの "外部的なリダイレクト" である [R] フラグを ReWriteRule 指示子で使う事です。
Tomcat が /servlet 以下のリクエストを受け付けません
もし httpd.conf の中に "<Location />" 指示子があるなら、 それらは ApJServMount 指示子よりも優先されます。 以下の例では "/servlet" リクエストは Tomcat へ転送されません。
ApJServMount /servlet /ROOT
<Location />
Options Indexes Multiviews
</Location>対処としては <Directory> 指示子を <Location> 指示子の代わりに使うことです。
どうすれば Tomcat を "nobody" 権限で自動的に起動できますか?
もしあなたの UNIX 機に "rc.d" 形式のブートディレクトリがあるなら (Solaris, RedHat, その他)、一番簡単な方法は適切なブートディレクトリの下に以下のようなファイルを作ることです。
#!/bin/sh
CLASSPATH=/your/classpath/here
export CLASSPATH
su - nobody -c "/tomcat/bin/tomcat.sh $@"そうすれば (たとえば) Apache を開始するのと同じように、 ブートシーケンスから /etc/rc.d/init.d/tomcat (start | stop) としてこれを呼出すことができます。
mod_jk - 使いたい けど見つかりません。 どこにありますか?
このドキュメントを書いている時点(2000 年 9 月 30 日)では、 mod_jk は Tomcat ソース配布から構築しないといけません。
(訳注: 3.2.2 では Win32, Netware(!) 用のバイナリ配布があります。 )
mod_jk - Servlet や JSP を実行すると Apache が固まります
mod_jk は mod_jserv と違って Tomcat と通信するとき同じポートを再利用します。 Tomcat を再起動した時は必ず Apache も再起動する必要があります。
(訳注: ここでは ajpv13 の事を言ってると思われます。ajpv12 ではポートの再利用はしません。)
このドキュメントは Gal Shachor が作成しました。 その後、Rob Slifka とMike Bremford が別々のドキュメントに分割して、改訂しました。 貢献者達のアルファベット順リストです。
[訳注: これは鰈崎義之が翻訳しました。 日本語訳に対するコメントは、jajakarta-report@nekoyanagi.com 宛に送って下さい。]
Copyright ©1999-2000 The Apache Software Foundation |