Jul 032007
 

サイトのTopをTomcatで処理させたい場合、ROOTとしてウェブアプリケーションを配備すればよい、ということを書きました(サイトのTop自身もTomcatに処理させる)。

でも、アプリケーションをビルドする際にROOT.warとするのもちょっとイヤだったので、プロジェクト名.warで固めたアーカイブ(someproject.war)をROOTとして利用できる方法にチャレンジしてみました。

サイトURLはhttp://www.example.com/と仮定します。

server.xmlへの仮想ホスト設定

Hostコンテナでwww.example.comを定義します。

<Host name="www.example.com" deployXML="false"
         appBase="/var/tomcat5/sites/www.example.com"
         unpackWARs="true" autoDeploy="true" 
         xmlValidation="false"
         xmlNamespaceAware="false">
</Host>

ROOT.xmlを用意

docBaseにwarファイルへの絶対パスを指定したROOTコンテキストファイルを用意します。

<Context path="" docBase="/usr/local/webapps/someproject.war" debug="0" reloadable="true">
</Context>

warファイルの置き場所はHostコンテナのappBaseには含めないようにします。
ROOT.xmlの置き場所は$CATALINA_HOME/conf/Catalina/www.example.com/配下になります(厳密には$CATALINA_HOME/conf/[enginename]/[hostname]/以下です)。

これでTomcatを起動すると/usr/local/webapps/someproject.warが/var/tomcat5/sites/www.example.com/ROOTとして展開されて、www.example.comのサイトTopとして利用できるようになります。

ちなみにこの応用として、Context定義をROOT.xmlではなくsubdir.xmlで用意すれば、www.example.com/subdirとして配備することも可能になります。

Jun 302007
 

HostコンテナでappBaseを指定して、conf/Catalina/[hostname]/context.xmlでのdocBaseをappBaseからの相対パスのつもりで書いたらエラーになった。

A docBase xxxx inside the host appBase has been specified, and will be ignored

appBaseの中にdocBaseがいてはダメなのだったのか。

Jun 292007
 

タイトル変かもしれません。
http://www.example.com/のトップレベルからTomcatに処理させたい場合。Tomcatだけでウェブサーバ公開すれば、っていう突っ込みはなしでお願いします。

Apacheでは以下のように仮想ホストを設定。

<VirtualHost *:80>
  ServerName www.example.com
  JkMount /* ajp13
</VirtualHost>

Tomcat側ではappBaseである/var/tomcat5/webapps/直下にアプリを配備したとする。
サブディレクトリがあるわけではなく、/var/tomcat5/webapps/index.jspのようになっている状態。

はじめはこれでいいのだろうと思いましたが、うまくいきません。

/var/tomcat5/webapps/ROOT/index.jspのように、ROOTというディレクトリをはさむ必要があります。
Tomcatウェブサーバのトップページと同じ構造です。

ROOT.warとしてビルドしてwebappsにおいてしまうのが一番簡単です。ROOT.war以外のファイル名にしたい場合は、ROOT.xmlのContextでdocBaseに直接warファイル名を記述するようにすればよいです。

<Context docBase="/path/to/hogehoge.war">
</Context>

Eclipseのプロジェクト名のままwarにしてROOTアプリケーションとして配備したいような場合に有用でしょう。

参考:

Jun 282007
 

ColdFusion自体をウェブアプリケーションとしてTomcat上にデプロイする場合はこちら。

ColdFusionとTomcatを別々に動かす場合、そのままだと*.jspの制御はColdFusionに奪われてしまい、Tomcatで処理することができない。
AddHandler jrun-handlerから.jspを外しても変わらない。
実はColdFusion側でservlet-mappingの定義変更が必要になる。

上のサイトではservlet定義とservlet-mappingの定義をすべて無効にしているが、*.jspだけに限れば、その分のservlet-mappingを無効にするだけでもよいはず。

# diff -u runtime/servers/default/SERVER-INF/default-web.xml.orig runtime/servers/default/SERVER-INF/default-web.xml
--- runtime/servers/default/SERVER-INF/default-web.xml.orig 2003-05-27 11:36:10.000000000 +0900
+++ runtime/servers/default/SERVER-INF/default-web.xml 2007-06-27 23:36:37.000000000 +0900
@@ -81,10 +81,12 @@
    <url-pattern>/</url-pattern>
  </servlet-mapping>

+ <!--
  <servlet-mapping>
    <servlet-name>JspLicenseServlet</servlet-name>
    <url-pattern>*.jsp</url-pattern>
  </servlet-mapping>
+ -->

  <servlet-mapping>
    <servlet-name>JSTServlet</servlet-name>

あとはhttpd.confで

  • AddHandler jrun-handlerから.jspを外す
  • JRunConfig Ignoresuffixmapをfalseからtrueに変更(CFMX7の場合)

をおこなえばよい。

Jun 282007
 

mod_jkを使ってApacheとTomcatを連携される際、Tomcat側で処理させるURLパスをJkMountディレクティブで指定しますが、開発環境など変更が激しい環境ではこの定義変更にApache再起動が必要になってしまうので不便なときがあります。

httpd.conf

JkMount /jsp-examples/* ajp13
JkMount /servlets-examples/* ajp13

これをApache再起動なしで変更したい場合は、uriworkermap.propertiesを使って定義を外だしにしておくと便利です。

httpd.conf

JkMountFile conf/uriworkermap.properties 
JkMountFileReload 60 

uriworkermap.properties

/jsp-examples/*=ajp13
/servlets-examples/*=ajp13

こうしておくとuriworkermap.propertiesを書き換えた60秒後には変更が反映されることになります。
JkMountFileReloadが再読み込みの間隔で、デフォルトは60秒。0を指定すると無効化できます。
mod_jk 1.2.20以降で利用できます。

本番では無用なミスを避けるためにも、JkMountを使うか、JkMountFileReload 0にしておくことをお勧めしますが 😛

Jun 052007
 

bin/catalina.shのコメントに書かれているように、stop時も使われるかが違うだけです。

CATALINA_OPTS
Java runtime options used when the “start”, or “run” command is executed.
JAVA_OPTS
Java runtime options used when the “start”, “stop”, or “run” command is executed.

例えば-Xmx指定などは、本来CATALINA_OPTSで十分なはずです。
また、gcログの出力ファイル名に起動時の日時をつけたい場合なども、起動時だけ有効なCATALINA_OPTSを使うと簡単におこなえます。

CATALINA_OPTS="-XX:+PrintGCDetails -Xloggc:$CATALINA_HOME/logs/gc.`date '+%Y-%m-%d-%H%M%S'`.log"

JAVA_OPTSに指定すると、停止用に起動されたjvm分の余計なファイルができちゃいますが、CATALINA_OPTSなら本来ほしいTomcat分のgcログだけにできるはずです。

私はこれを$CATALINA_HOME/bin/setenv.shに書くようにしています。

May 292007
 

TomcatのウェブフロントエンドにApacheを使っている場合、Tomcatの出力結果に対してApacheのSSI処理を施すことができます(Tomcatの、ではなく)。

例えば

JkMount /jsp-examples/* ajp13
<Location /jsp-examples>
  SetOutputFilter INCLUDES
</Location>

とした場合、jsp-examplpes配下のjspファイルにSSIを仕込むことができます。
AddOutputFilterだとファイル拡張子の指定が必要になってしまうので、SetOutputFilterを使うのがポイントです。試してませんがAddOutputFilterByTypeでも大丈夫かも知れません。

以下、jsp-examples/snp/snoop.jspに仕込んで試したコードです。

$ diff -u snoop.jsp.orig snoop.jsp
--- snoop.jsp.orig      2007-03-06 00:26:05.000000000 +0900
+++ snoop.jsp   2007-05-29 17:02:50.000000000 +0900
@@ -52,5 +52,9 @@
 The browser you are using is <% out.print(util.HTMLFilter.filter(request.getHeader("User-Agent"))); %>
 <hr>
 </font>
+<pre>
+<!--#printenv -->
+</pre>
 </body>
+<!--#include virtual="/footer.html" -->
 </html>

virtualの場合ApacheのDocumentRootからのパスになります。fileのときは試してません 😛

Apache 2.2でTomcatバランシング実験

 article  Comments Off on Apache 2.2でTomcatバランシング実験
Dec 202006
 

Apache 2.2のproxyモジュールを使って複数のTomcatに負荷分散。
HTTPリクエストをReverse Proxyするのではなく、mod_jkを使って接続するわけでもなく、mod_proxy_ajpを使ったAJP13プロトコル接続で負荷分散してみようという試みです。

こんな感じでできるだろうかと、Solaris 10マシンで試してみました。
Apache 2.2とTomcat5はCSWパッケージ版を導入して、もうひとつのTomcat5を公式サイトのバイナリで導入し、ポート番号のみ変更して動かしてます。

ProxyRequests Off

<Proxy *>
  Order deny,allow
  Allow from all
</Proxy>

<Location /jsp-examples>
  ProxyPass balancer://appservers/jsp-examples stickysession=JSESSIONID nofailover=Off
  Order Deny,Allow
  Allow from all
</Location>

<Proxy balancer://appservers/jsp-examples>
  BalancerMember ajp://127.0.0.1:8009
  BalancerMember ajp://127.0.0.1:8010
</Proxy>

<Location /servlets-examples>
  ProxyPass balancer://appservers/servlets-examples stickysession=JSESSIONID nofailover=Off
  Order Deny,Allow
  Allow from all
</Location>

<Proxy balancer://appservers/servlets-examples>
  BalancerMember ajp://127.0.0.1:8009
  BalancerMember ajp://127.0.0.1:8010
</Proxy>

<Location /balancer-manager>
  SetHandler balancer-manager
  Order Deny,Allow
  Deny  from all
  Allow from ::1 127.0.0.1 192.168.0.0/24
</Location>

とりあえずTomcatについてくるjsp-examplesとservlets-examplesは動作したのですが…

実は最初、

<Location /jsp-examples>
  ProxyPass balancer://appservers stickysession=JSESSIONID nofailover=Off
  Order Deny,Allow
  Allow from all
</Location>

<Proxy balancer://appservers>
  BalancerMember ajp://127.0.0.1:8009
  BalancerMember ajp://127.0.0.1:8010
</Proxy>

という定義を試していました。
ところが/jsp-examplesにアクセスするとTomcatのトップページが表示されてしまうので、前述のやりかたに変更したものの、正しいやりかたなのかよくわかりません。

ちなみに/balancer-managerの状態はこちら。

Apache balancer status

Worker URLのエントリ自体も重複していますし、ステータスがエラーになっているものもあります。やはり何かしらやりかたを間違えているような気がします… 😕

■2006-12-24追記
こんな感じでできました。ProxyPass先にURLパスまで指定する必要があったようです。

<Location /jsp-examples>
  ProxyPass balancer://appservers/jsp-examples stickysession=JSESSIONID nofailover=Off
  Order Deny,Allow
  Allow from all
</Location>

<Proxy balancer://appservers>
  BalancerMember ajp://127.0.0.1:8009
  BalancerMember ajp://127.0.0.1:8010
</Proxy>
Nov 222006
 

Tomcat起動時のJVMオプションを$CATALINA_OPTSや$JAVA_OPTS環境変数に設定する情報をよく見かけます。

これらの変数は、起動前にコマンドラインで設定しようとか、~/.bashrcに書いておこうとか、catalina.shを書き換えようといったハナシで大抵終わっているのですが、setenv.shファイルを用意する、という方法もあります。

実は起動スクリプトのcatalina.shには「setenv.shがあれば読み込む」というコードが仕込まれています。

if [ -r "$CATALINA_HOME"/bin/setenv.sh ]; then
  . "$CATALINA_HOME"/bin/setenv.sh
fi

ですので、このファイルを用意して(デフォルトでは存在しません)、

CATALINA_OPTS="-server -Xmx512M"

とでもしておけば、簡単に設定することができるようになっているのです。

この方法のメリットは、ユーザが手動なりprofileなりでいかなる環境変数を設定していても影響をうけなくなることです。無理やりリセットすることになりますから。
suの方法によってはprofile読まれなかったりすることもありますからねー。

本番環境で使われる場合や、catalina.shを書き換えるぐらいなら、setenv.shの利用をおすすめしておきます。

余談ですがCLASSPATHはsetenv.shでは設定できません。
catalina.shを更に眺めていくとよくわかるのですが、setenv.shのあとにsetclasspath.shというファイルを読み込んで、その中で初期化しているためです。

Jul 252005
 

前回は「LogManager関連の警告が出てまともに動作しない」状態でした。

WARNING: System property “java.util.logging.manager” should be the name of a subclass of java.util.logging.LogManager

こちらはSableVMのWikiドキュメントを見ていたら解決できました(たぶん)。
Getting jakarta-tomcat running with SableVM
こちらのTomcatバージョンは5.0.19ですが、同様の設定をおこなうことで正常状態になったと思われます。少なくともcatalina.outは出力されるようになりました。
LogManagerに関しては、JAVA_OPTSでproperty指定する必要があるようです。
例ではjikes_optsというスクリプトを作るようになってますが、せっかく仕組みが用意されているのでsetenv.shに以下のように書いています。

# cat /usr/local/jakarta-tomcat-5.5.9/bin/setenv.sh
JAVA_HOME="/usr/lib/sablevm"
JAVA_OPTS="-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog"
CATALINA_OPTS="-Dbuild.compiler.emacs=true"

LogManagerの件に関してはJAVA_OPTSの記述が効いているのだというのは想像つくのですが、詳細はよくわからないのでこれから勉強しようと思います。