Java EEアプリを本リリースする際にやるべきこと

Apache, Tomcat, ajp, Java

Java EEのアプリというのは、大抵、独自のサブディレクトリーに配置されるものである。

例えば、myapp.war を Tomcat で開発しているときに、開発者は http://localhost:8080/myapp/ にアクセスして動作確認するだろう。

開発作業についてはそれで何も問題ないのだが、実際にウェブサイトを公開することを考えると、2つの点でこれは現実的ではない。

1つは、8080ポートでウェブサイトを公開すべきでないという、ごく当たり前のことだ。
インターネットからアクセスされるサーバーが余計なポートを解放すべきではないし、ウェブサーバーとしてはTomcatよりもApache httpdの方が信頼できる。
この点についてはajpで解決するのが一般的だ。
Java以外のウェブアプリについても、Apache経由でアクセスさせるのはよくある一般的なやり方だと思われる。

もう1点、これはおそらくJava EE特有の問題だと思うのだが、/myapp というサブディレクトリー必要になってしまうという点だ。

webapps/myapp.war

としてデプロイする限りこれは仕様上必然である。

コンテキストルートへデプロイするには、ROOT.war という名前にしなければならない。

しかしROOT.warにすると、1つのTomcatインスタンスで1つのウェブアプリしか公開できないことになってしまう。

例えば、1つのウェブサーバーで、2つのJavaウェブアプリを公開したいとする。

2つドメイン名を取得して、それらを1つのサーバー(IPアドレス)としてDNSのAレコードを登録したとしよう。

http://my-site.com/
http://my-other-site.com/

本来↑このようにしたいところだが、ROOT.warを2つ作ることはできないので、

http://my-site.com/myapp1
http://my-other-site.com/myapp2

という不細工なURLになってしまう。


こういった問題は、Apache側の設定で回避することができる。

例えば、以下のようにリダイレクトさせてしまう。


httpd.conf

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    ProxyPass /myapp !
    ProxyPass / ajp://localhost:8009/myapp/
    ProxyPassReverse / ajp://localhost:8009/myapp/
    RedirectMatch 301 ^/myapp$ /
    RedirectMatch 301 ^/myapp/(.*)$ /$1
</VirtualHost>


ProxyPass / ajp://localhost:8009/myapp/
ProxyPassReverse / ajp://localhost:8009/myapp/
この設定で、example.comという仮想ホストに対するアクセスをajpTomcatに流すようにする。


ProxyPass /myapp !
Java EEアプリはmyapp.warとして開発しているとすると、内部からは /myapp/some-servlet のURLにアクセスしているはずなので、それはプロキシーしない。(後の設定でリダイレクトする)


RedirectMatch 301 ^/myapp$ /
RedirectMatch 301 ^/myapp/(.*)$ /$1
/myapp 以下に対するアクセスは / へリダイレクトして、先のプロキシー設定により、ajpを経てTomcatへ流す。


とまあ、こんな感じで対応できるのだが、301の使い方として適切ではないと思うし、毎回のようにリダイレクトが発生するのは通信効率上よろしくないと言えるだろう。

もっとまともなソリューションはないものか。

と悩んでいたところ、Tomcatのserver.xmlドメインごとのROOT.xmlで対処できるそうな。


【参考】
http://www.matsuaz.com/matsumotojs/2011/02/02/1296583161582.html


なるほど。

サイトごとに、

$CATALINA_HOME/conf/Catalina/my-site.com/ROOT.xml

を作成して、docBaseに.warファイルのパスを指定すれば良いのか。

かぁんたんですね。