【真夏の夜のミステリー】Tomcatを殺したのは誰だ?:現場から学ぶWebアプリ開発のトラブルハック(6)(3/3 ページ)
本連載は、現場でのエンジニアの経験から得られた、APサーバをベースとしたWebアプリ開発における注意点やノウハウについて解説するハック集である。現在起きているトラブルの解決や、今後の開発の参考として大いに活用していただきたい。(編集部)
【第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システムの開発支援にかかわる。最近では、主にオープンソースのアプリケーションサーバに関する検証や技術支援、トラブルシューティングに明け暮れている
- 数百キロのコードでブルー - ドクターTomcat緊急救命
- DB操作の“壁”を壊すJPAが起こした「赤壁の戦い」
- アプリ開発でも、よ〜く考えよう。キャッシュは大事だよ
- スレッドダンプの森で覚えた死のロックへの違和感
- ThreadとHashMapに潜む無限回廊は実に面白い?
- JavaのGC頻度に惑わされた年末年始の苦いメモリ
- 肥え続けるTomcatと胃を痛めるトラブルハッカー
- 【トラブル大捜査線】失われたコネクションを追え!
- 【真夏の夜のミステリー】Tomcatを殺したのは誰だ?
- OutOfMemoryエラー発生!? GCがあるのに、なぜ?
- DBアクセスのトラブルは終盤で発覚しがち……
- 【実録ドキュメント】そのログ本当に必要ですか?
- “Stop the World”を防ぐコンカレントGCとは?
- Webアプリの問題点を「見える化」する7つ道具
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- Tomcatの環境を構築する
やり直し「JSPとTomcat」(2) JSPの実行環境となる「Webコンテナ」の1つ、「Tomcat」を実行するための環境を構築し、次回以降の実習環境を作ります - サーブレット/JSPの開発環境を作る
[連載]基礎から学ぶサーブレット/JSP(3) サーブレット/JSPの開発/実行環境を整えるためにJ2SE、Tomcat、Apacheのインストールを行います - Apache 2.2でWebサイトをパフォーマンスアップ!
最新Apacheの機能と設定方法教えます 最新安定版Apache 2.2は、何が変わったのか? 最新のApacheを新機能の使い方とともに解説する - 事例に学ぶWebシステム開発のワンポイント
現場のエンジニアの経験から得られた、アプリケーション・サーバをベースとしたWebシステム開発におけるノウハウ、注意点について解説 - 第1回 クラスタ化すると遅くなる?(2002/3/9)
- 第2回 キャッシュが性能劣化をもたらす謎を解く(2002/3/23)
- 第3回 クラスタは何台までOK?(2002/4/19)
- 第4回 マルチスレッドのいたずらに注意(2002/5/14)
- 第5回 クラスタによるアプリケーションの動的アップデート(2002/6/4)
- 第6回 APサーバからの応答がなくなった、なぜ?(2002/11/30)
- 第7回 低負荷なのにCPU使用率が100%?(2002/12/11)
- 第8回 文字化け“???”の法則とその防止策(2003/1/28)
- 第9回 メモリは足りているのに“OutOfMemory”のなぞ(2003/2/15)
- 第10回 レスポンスキャッシュでパフォーマンス向上(2003/3/29)
- 第11回 JDBC接続を高速化―PreparedCacheの活用(2003/4/18)
- 第12回 ブラウザキャッシュでパフォーマンス向上(2003/5/10)
- 第13回 ファイルアップロード/ダウンロードに潜むわな(2003/6/12)