連載
» 2007年08月27日 00時00分 公開

現場から学ぶWebアプリ開発のトラブルハック(6):【真夏の夜のミステリー】Tomcatを殺したのは誰だ? (3/3)

[金子崇之,NTTデータ先端技術]
前のページへ 1|2|3       

【第6章】解決

 原因が分かれば対処は簡単だ。今回のシステムでは、TomcatのmaxThreads値を350に変更した。

 Apacheの全スレッド数より50多く設定した理由は、Apacheからの再接続が発生した際でも耐えられるよう、多少余裕を持つようにしたためである。どれくらい余裕を持てばよいかは、各システムの状況によって異なる。今回のシステムではこの設定変更以降、無応答となる事象は起こらなくなった。

負荷テストをしていたのに、なぜ問題が発見できなかったのか?

 今回のシステムでは冒頭で述べたとおり、試験環境で負荷試験を行っていた。それにもかかわらず、なぜこの問題が発見できなかったのか?

 実は、後から分かったことだが、負荷試験の際、APサーバの台数は本番環境と同じ2台用意したが、マシン台数を確保できなかったため、負荷の低いWebサーバは1台で試験を行っていた。そのため、スレッド数は抑えられ、この問題を発見できなかったのだ……

【Tips】ApacheとTomcatを連携するときの3つのポイント

 今回のトラブルはApacheとTomcatとの連携に関する設定値をきちんと理解していなかったために発生したといってよいだろう。そこで、ここでは特に重要となる設定値について、注意点を挙げておく。

【1】Tomcatのスレッド数とApacheのコネクション数

 Tomcatのスレッド数がApacheからのコネクション数に対して不足すると、無応答やエラーの原因となる。そのため、Tomcatのスレッド数が常に上回っているように設定する。

 Apacheからのコネクション数の最大値は、ApacheのMPM(Multi Processing Module)の設定によらず、MaxClientsの値になる。

 Tomcatのスレッド数は、Connector要素のmaxThreads属性で設定する。古いTomcat(バージョン5.0以前)では、maxProcessorsという属性名になっている。また、Connectorは受け付けるportごとに設定するので、異なるportに設定してしまわないよう注意してほしい。

 なお、Apacheが複数台存在し、それぞれ複数台のTomcatに負荷分散を行っているような環境では、Tomcatに接続してくるすべてのApacheのMaxClients値の総和が必要となる。

【2】張りっ放しのコネクションのタイムアウト

 一定時間やりとりがないApacheとTomcatの間のコネクションをいったん切って、Tomcatのスレッドをプールに戻すことができる。システムの安定化につながる以下のような効果が期待できる。

  • 接続先のサーバに障害があった場合にコネクションに結び付いたスレッドを解放する
  • ApacheとTomcatの間にファイアウォールなどがあった場合、コネクション張りっ放しによる不具合を防ぐ

 ただし、高負荷環境ではコネクションを切ることができないため、残念ながらmaxThreadsの値を下げる効果はない。

 TomcatのConnector要素のconnectionTimeout属性で、コネクションのタイムアウト値を設定する。デフォルト値は0(無限大)である。

 また、mod_jk側でもconnection_pool_timeoutにより、一定時間やりとりがないコネクションを再利用せずに破棄できる。こちらもデフォルト値は0(無限大)である。

【3】mod_jkのタイムアウト値

 mod_jkでは、各種タイムアウト値を設定できる。これらのパラメータを適切に使用すれば、問題発生時に無応答を回避し、フェイルオーバやユーザーにエラーページを返すことが可能となる。

  • socket_timeout:ApacheとTomcatの間のコネクションのタイムアウト値。OSに渡される
  • connect_timeout、prepost_timeout:Tomcatにリクエストを転送する前に行う生存確認のタイムアウト値
  • reply_timeout:Tomcatにリクエストを転送した後、応答を得るまでのタイムアウト値
  • recovery_options:負荷分散環境において、Tomcatがダウンした場合のフェイルオーバの挙動を指定する

 これらのパラメータについての詳細はmod_jkのドキュメントを参照してほしい。

【最後に】ログから目を離すな!

 本記事では、Tomcatのスレッド数に関するトラブル事例を紹介し、Apacheとの連携における注意点を示した。

 今回の事例からは、負荷試験についての教訓も得られる。負荷試験を行う際は、本番相当のサーバ台数、データ量、トラフィックを用意するのが基本だ。しかし、何らかの制約により本番環境と試験環境に差がある場合には、その差が生むシステムへの影響を十分に考慮しておく必要がある。

 また、当たり前のことではあるが、トラブル解析においてはログの解析が非常に大事だ。今回のトラブルでも、ログの解析がもっと早く終わっていれば、もっと早くトラブルを解決できたかもしれない。出力レベルについても、トラブル解析に必要な情報を出力できているかどうかを確認しておく必要がある。

 トラブルが発生してからログを解析するのではなく、ログを常時監視する仕組みを導入すべきだろう。

プロフィール

金子崇之

金子 崇之(かねこ たかゆき)

NTTデータ先端技術株式会社 オープンソース事業部所属。
入社よりJavaを用いたWebシステムの開発支援にかかわる。最近では、主にオープンソースのアプリケーションサーバに関する検証や技術支援、トラブルシューティングに明け暮れている



前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。