mod_proxy_ajp
※この記事は以前のブログからの転載です。
結構前の話なんだけど、
Apache 2.2 から mod_proxy_ajp が組み込まれました。
これは Tomcat とApache を連携するものです。
Apache 2.2.0 は怖いので使っていなかったのですが、
Apache 2.2 もバージョンが進んだので使ってみることにしました。
--enable-proxy 付きでコンパイルして
<Location /hoge/> ProxyPass /hoge/ ajp://localhost:8009/hoge/ </Location>
とすることで /hoge/ へのアクセスをTomcatへ渡せます。
だがしかし、これでは静的コンテンツもTomcatに渡してしまい、
連携するメリットがあんまり感じられない。
↑(アクセス制御とかそれらの面は別として、パフォーマンスの面で)
Tomcat に渡すものは動的コンテンツのみであるのが望ましいので
/servlet/* は
ProxyPass /servlet/ ajp://localhost:8009/servlet/
とすることで渡すことができます。
問題はjspです。
jspだけを渡すことができません。
いや、できないというのは言い過ぎでできないこともないです。
mod_rewrite を使って
RewriteEngine On RewriteCond %{REQUEST_URI} (.*).jsp(.*) RewriteRule ^/(.*) ajp://localhost:8009/$1 [P]
とやると、一応できます。
これでOKだと思うのは早計です。
ここでパフォーマンスをチェックしてみます。
感覚的に上のjspの処理は遅そうなので。
早速パフォーマンスを測定してみます。
実行したソースは、
import java.io.*; import java.text.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class test extends HttpServlet{ private static final String CONTENT_TYPE = "text/html; charset=windows-31j"; private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); out.println(formatter.format(new Date())); } }
<%@ page contentType="text/html; charset=windows-31j" %> <%@ page import="java.text.*" %> <%@ page import="java.util.*" %> <%! private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); %> <%= formatter.format(new Date()) %>
こんな感じの単純なものです。
ab -n 1000 -c 64 http://hostname/test.jsp ab -n 1000 -c 64 http://hostname/servlet/test
にて測定しました。
測定結果は以下のようになりました。
mod_proxy_ajp + mod_rewrite - jsp Requests per second: 241.78 [#/sec] mod_proxy_ajp + mod_rewrite - servlet Requests per second: 1174.78 [#/sec] mod_jk - jsp Requests per second: 1097.32 [#/sec] mod_jk - servlet Requests per second: 1174.78 [#/sec]
うわぁ・・・mod_proxy_ajp + mod_rewrite - jspの処理・・すごく遅いナリ・・・
大体予想通りなのですが、
mod_proxy_ajp - jsp はやはり mod_rewrite を通して行っているので、
とても遅いです。
connection pooling も使えません。
でもこのまま終わるのは悔しいので試行錯誤してみました。
jsp の処理を mod_rewrite を使用することにより、
パフォーマンスが低下してしまうことに関しての
解決策を見つけました。
そもそもjspの処理が遅くなっていた原因は、
mod_rewriteを使用することにより、
mod_proxy_ajp からの、バックエンドサーバへのコネクションが、
再利用されないところにあると考えました。
そこで、再利用の処理を、
mod_proxy_balancer にやってもらおうと言うわけです。
<Proxy balancer://ajp-balancer> BalancerMember ajp://localhost:8009 </Proxy> ProxyPass /servlet/ balancer://ajp-balancer/servlet/ RewriteRule ^/(.+).jsp(.+)? balancer://ajp-balancer/$1.jsp$2 [P,L]
こんな処理をすることにしました。
さあ、期待に胸膨らませて
ab にてテストをしましょう。
Requests per second: 1296.83 [#/sec]
きたああああああああああああああああ!!!!
どうせだから servlet での値も測定してみましょう。
Requests per second: 1331.42 [#/sec]
こっちもきたあああああああああああああ!!!!
ということで、
mod_proxy_ajp を使用する場合はクラスタ化する必要がなくても、
mod_proxy_balancer を使いましょう。
さようなら mod_jk 今までありがとう
追記
ProxyPass /servlet/ balancer://ajp-balancer/servlet/ stickysession=JSESSIONID RewriteRule ^/(.+).jsp(.+)? balancer://ajp-balancer/$1.jsp$2 [P,L] stickysession=JSESSIONID
としたら、セッションも渡せましたとさ。
※この記事は以前のブログからの転載です。