kuniku’s diary

はてなダイアリーから移行(旧 d.hatena.ne.jp/kuniku/)、表示がおかしな箇所はコメントをお願いします。記載されている内容は日付およびバージョンに注意してください。直近1年以上前は古い情報の可能性が高くなります。

Apache2.4 windows32bit

Apache windows版の設定いろいろ

-access.log,error.logを日付でローテーションする(日本時間)

  • ファイル Apache24/conf/httpd.conf
  • Windowsの「\」バックスラッシュでなく、「/」スラッシュで記載すること、日本時間 D/tokyo 0時にローテーションされるよにするので、540を指定する。


#ErrorLog "logs/error.log"
ErrorLog "|C:/Apache24/bin/rotatelogs.exe C:/Apache24/logs/localhost_error_log.%Y-%m-%d.txt 86400 540"


CustomLog "|C:/Apache24/bin/rotatelogs.exe C:/Apache24/logs/localhost_access_log.%Y-%m-%d.txt 86400 540" common

「%D」が処理時間をミリ秒で出力。%Tだと秒で出力。
tomcatアクセスログのフォーマットもApacheと同じ。


# LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%h %l %u %t \"%r\" %>s %b %D" common

windows用のmpmの設定

Windowsapacheはプロセスを生成せずに、スレッド生成する仕組みのため、スレッド関係の設定を行う

  • httpd.confでは、mpmの設定でIncludeはコメントのためコメントを外す


#
Include conf/extra/httpd-mpm.conf

    • httpd-mpm.confの編集


デフォルト150です、そんなにスレッド生成される必要ないってことで、75(半分)に。
# WinNT MPM
# ThreadsPerChild: constant number of worker threads in the server process
# MaxConnectionsPerChild: maximum number of connections a server process serves

#ThreadsPerChild 150
ThreadsPerChild 75
MaxConnectionsPerChild 0

tomcatとの連携でmod_jk1.2を使う場合

    • mod_proxyを使うことが推奨されていると思うが、mod_jkを使う必要がある場合は、mod_jk2.0がメンテナンスされていないみたいなので、1.2系の最終版を使う。
    • 同一サーバ内でのApacheからTomcatajpポート8009)を連携する


#mod-jk tomcat
Include conf/extra/httpd-mod_jk.conf

http://ftp.meisei-u.ac.jp/mirror/apache/dist/tomcat/tomcat-connectors/jk/binaries/windows/
から以下をダウンロード
tomcat-connectors-1.2.40-windows-i386-httpd-2.4.x.zip
Windows 32bit版では、i386じゃないと動かない(tomcat-connectors-1.2.40-windows-x86_64-httpd-2.4.x.zipだと動かない).


#mod_jkを利用して、tomcat4.1.30と連携する
LoadModule jk_module modules/mod_jk.so


# Where to find workers.properties
#JkWorkersFile c:/Apache24/conf/workers.properties
JkWorkersFile conf/workers.properties

# location of log file
JkLogFile c:/Apache24/logs/mod_jk.log

# log level
JkLogLevel info

# Select the log format
#JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"

# JkOptions indicate to send SSL KEY SIZE,
#JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

# JkRequestLogFormat set the request format
#JkRequestLogFormat “%w %V %T”

#Send everything for context /test to worker ajp13

#example
#JkMount /test tomcatA
#JkMount /test/* tomcatA

#workers.properties で定義する testWorker1 に /* ( すべてのリクエスト ) をマッピングするという意味になります。
#JkMount /* testWorker1

# コンテキストパス /websample/ に対するすべてのリクエストを testWorker1 にマッピングする
#JkMount /examples/* testWorker1

JkMount /examples/* ajp13

      • Apache24/conf/workers.propertiesの配置と編集

jk2の場合は、「workers2.properties」だったりするけど、1.2なので「workers.properties」とする。


#Configure workers.properties
# Define workers
worker.list=tomcatA
## Set properties
#worker.tomcatA.type=ajp13
#worker.tomcatA.host=localhost
#worker.tomcatA.port=8009

#worker.list=testWorker1
#worker.testWorker1.port=8009
#worker.testWorker1.host=localhost
#worker.testWorker1.type=ajp13

#----ここから設定した場合のサンプル
worker.list=ajp13
worker.ajp13.type=ajp13
# Sets the version of AJP used. The AJP listeners defined in Geronimo are AJP v13.
worker.ajp13.host=localhost
# Specifies the location of the Geronimo server. Use default localhost for single-tier scenarios. Specify the hostname of the Geronimo server for multi-tier environments.

worker.ajp13.port=8009
# Both Tomcat and Jetty come with a predefined AJP13 listener on port 8009


Apachetomcatの1インスタンスをmod_proxyを使って連携する

mod_proxy関係の設定を記載するファイルを用意して、配置する

ファイルを読み込むようにする


Include conf/extra/httpd-proxy-test.conf

  • httpd-proxy-test.confの編集
    • mod_proxy_httpを利用する場合、tomcatのHTTPは8080ポートを使う想定


LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_module modules/mod_proxy.so



#httpプロトコルで通信、moduleを有効にして、かつ以下の設定
ProxyPass http://localhost:8080/examples/


#ディレクティブ設定を使わない場合は、下記のようになる
#ProxyPass /examples/ http://localhost:8080/examples/

    • mod_proxy_ajpを利用する場合、tomcatAJPは8009ポートを使う想定


LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so



#ajpプロトコルで通信
ProxyPass ajp://localhost:8009/examples/


#ディレクティブ設定を使わない場合は、下記のようになる
#ProxyPass /examples/ ajp://localhost:8009/examples/

Apachetomcatの複数インスタンスを連携する

mod_proxy関係の設定を記載するファイルを用意して、配置する
Include conf/extra/httpd-proxy-test2.conf

ファイルを読み込むようにする


Include conf/extra/httpd-proxy-test2.conf

  • httpd-proxy-test2.confの編集

tomcatが2インスタンスだとして、ajpポートは、8009,9009とした場合
Apacheからtomcatラウンドロビンのため、route=xxの指定はしない。


LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule status_module modules/mod_status.so

ProxyPass /balancer-manager !

SetHandler balancer-manager
Order Deny,Allow
Deny from all
#Allow from 192.168.1.0/24 #セグメントで許可
#Allow from 127.0.0.1 ::1 #localhostのみ許可
Allow from all #全てから許可、運用時は使わない

ProxyRequests off
ProxyPass /examples/ balancer://texamples/ nofailover=Off timeout=5 lbmethod=byrequests

BalancerMember ajp://127.0.0.1:8009/examples keepalive=off retry=30 loadfactor=10 connectiontimeout=1
BalancerMember ajp://127.0.0.1:9009/examples keepalive=off retry=30 loadfactor=10 connectiontimeout=1


設定上の考慮点

  • BalancerMemberで、コンテキスト名の末尾にスラッシュをつけると、スラッシュが2つになる。

Apacheのaccesslogより^〜 /examples// HTTP/1.1」 の結果が表示されていた。

  • retry=xxの値は、そのBalancerMemberへの振り分けできるかのチェックを、指定した間隔の秒ごとに行う。

例えば、1つのtomcatインスタンスを再起動中に、apacheからその再起動中のメンバーに
振り分けをしようとすると、そのメンバーには振り分けできない状況となる(ajp接続エラーとなる※1)。
次の振り分けタイミングチェックが、retryで指定した秒数経過した後に実行される。

※1:振り分けできなくても、別のメンバーに振り分けされるため、Apacheからの接続は、稼働しているtomcat側に
振り分けされる。

1つのtomcatインスタンスが再起動中の間は、ajpのコネクトでエラーとなるため
あまり短くすると、apacheから死んでるajpへ接続し、エラー発生頻度が上がる。
ajpのコネクトエラーが発生すると、そのリクエストはレスポンスが遅延する(遅延時間=0.5〜1秒程度)ことになる。
逆に、あまり長くしすぎると、バランスメンバーへの振り分けチェックが指定した秒数実行されないため
そのバランスメンバーが復帰(振り分け可能となる)が遅くなる。あいているリソースを使いこなせない。
tomcat起動時間を考慮して、tomcat起動にかかる時間+10秒くらいを設定すればよさそう。


Apachetomcatの複数インスタンスを連携するpart2(ProxyPassMatchを利用)

  • 実現したいこと
    • 特定のURLを、特定のBalancerMemberに振り分ける
    • BalancerMemberにホットスタンバイを設定する
    • 特定のURL以外のBalancerMemberを設定する

とした場合に、

    • HogeActionは、ajpの8009へ接続し、接続できないならば、ajp9009へ接続。
    • FooActionは、ajpの9009へ接続し、接続できないならば、ajp8009へ接続。
    • HogeAction、FooActionのどちらでもない場合は、ajpの9009へ接続し、接続できないならば、ajp8009へ接続。
  • httpd-proxy-test2.confの編集




ProxyPassMatch ^/webcontext/servlet/(HogeAcion.*)$ balancer://hogeAction/$1 nofailover=Off timeout=1 lbmethod=byrequests
ProxyPassMatch ^/webcontext/servlet/(FooAcion.*)$ balancer://fooAction/$1 nofailover=Off timeout=1 lbmethod=byrequests
ProxyPassMatch ^/webcontext/(.*)$ balancer://webcontextAll/$1 nofailover=Off timeout=2 lbmethod=byrequests


BalancerMember ajp://127.0.0.1:8009/webcontext/servlet keepalive=off retry=20 connectiontimeout=1
BalancerMember ajp://127.0.0.1:9009/webcontext/servlet keepalive=off status=+H retry=1 connectiontimeout=2


BalancerMember ajp://127.0.0.1:8009/webcontext/servlet keepalive=off status=+H retry=1 connectiontimeout=2
BalancerMember ajp://127.0.0.1:9009/webcontext/servlet keepalive=off retry=20 connectiontimeout=1


BalancerMember ajp://127.0.0.1:8009/webcontext keepalive=off status=+H retry=1 connectiontimeout=1
BalancerMember ajp://127.0.0.1:9009/webcontext keepalive=off retry=20 connectiontimeout=1



  • 記載時の注意点
    • ProxyPassMatchの記載順序に注意すること、特定のURL以外の処理は、最後に記載すること。
    • ProxyPassMatchは、正規表現を使うことができ、「()」の1つ目を、$1という変数に格納できる。2つ目ならば$2。


ProxyPassMatch ^/webcontext/servlet/(HogeAcion.*)$ balancer://hogeAction/$1 nofailover=Off timeout=1 lbmethod=byrequests
BalancerMember ajp://127.0.0.1:8009/webcontext/servlet keepalive=off retry=20 connectiontimeout=1

の意味は、
「/webcontext/servlet/」 より後を「$1」に格納し、バランサーhogeActionに「$1」を引き継ぐ.
BalancerMemberは、「/webcontext/servlet/」までのURIが決まった状態かつ、それ以降のURIが$1に
格納されていることと、BalancerMemberのajpで最後に「/」は付けないことから

ajp://127.0.0.1:8009/webcontext/servlet」+「/」+$1という形式でのURIになる

    • 特定のURL以外の場合は、


ProxyPassMatch ^/webcontext/(.*)$ balancer://webcontextAll/$1 nofailover=Off timeout=2 lbmethod=byrequests

「/webcontext/」 より後を「$1」に格納し、バランサーwebcontextAllに「$1」を引き継ぐ.
BalancerMemberは、「/webcontext/」までのURIが決まった状態かつ、それ以降のURIが$1に
格納されていることと、BalancerMemberのajpで最後に「/」は付けないことから

ajp://127.0.0.1:8009/webcontext」+「/」+$1という形式でのURIになる

  • 上記のProxyPassMatchの検証で、うまくいかずに、いろいろトライしている際に気づいたこと
    • 正規表現での値を格納させないで、URIのパスとBalancerMemberのパスをなんとか合わせる方法の例
    • 「/webcontext/servlet/HogeAcion」のリクエストを1つのajpに振りわけ、繋がらない場合はホットスタンバイに振り分ける。


ProxyPassMatch /webcontext/servlet/HogeAcion* balancer://hogeAction nofailover=Off timeout=10 lbmethod=byrequests

#こうかけない →BalancerMember ajp://127.0.0.1:9009/webcontext
#こうかけない →BalancerMember ajp://127.0.0.1:9009/webcontext/servlet
BalancerMember ajp://127.0.0.1:8009 keepalive=off retry=30 connectiontimeout=1
BalancerMember ajp://127.0.0.1:9009 keepalive=off status=+H retry=5

    • パスをなんとか合わせる方法でわかったこと
      • BalancerMemberには、「/webcontext/servlet/HogeAcion*」がそのまま渡される。
      • BalancerMemberのポート番号の後に、コンテキストやコンテキスト後のURIを記載すると存在しないURL(HTTPステータス404)となる。
        • 404 となる例は、 /webcontext/webcontext/servlet/HogeAcion* や /webcontext/servlet/webcontext/servlet/HogeAcion* のようになる
    • パスをなんとか合わせる方法での注意点
        • ProxyPassMatchの「/webcontext/servlet/HogeAcion・・・ 」全てがBalancerMemberに渡されるということ。