ServletコンテナとWebサーバ
ServletコンテナとWebサーバの接続形態
- 形態形態の種類
- スタンドアローンServletコンテナ…Tomcat
- ServletコンテナがWebサーバの機能を持つ
- 利点: レスポンスタイムが良い.
- 欠点: Webサーバとしての機能が不足しがち.
- プロセス内Servletコンテナ…Tomcat(3.2以降) + Apache (2.0以降)
- 同じプロセス空間内でServletコンテナを起動
- 利点: レスポンスタイムが良い.
- 欠点: スケーラビリティに劣る.
- プロセス外Servletコンテナ…Tomcat + Apache
- 異なるプロセス空間内でServletコンテナを起動
- 利点: スケーラビリティに優れる.
- 欠点: レスポンスタイムが若干悪い.
- プロセス内Servletコンテナかプロセス外Servletコンテナが望ましい
- Webサーバとしての機能が豊富である.
- GCがらみの問題が発生するとServletコンテナ全体がブロックするので,Webサーバを分離しておくとよい.
- Servletコンテナに関係ないリクエストを処理できる.
- Servletコンテナへのリクエストに対してタイムアウトを設定できる.
- プロセス内Servletコンテナを選択する場合
- プロセッサ数が多い高性能なサーバが用意できる.
- OSレベルでスレッドに対応している.
- Webサーバがマルチスレッド化されている.
- 処理遅延を短くしたい.
- プロセス外Servletコンテナを選択する場合
- プロセッサ数が多い高性能なサーバが用意できないが,多くのリクエストを処理しなければならない.
- OSがスレッドに対応していない.
- Webサーバがマルチスレッド化されていない.
- 複数のマシンに負荷分散したい.
Servletコンテナのスレッドプール
- スレッドプールの2つの機能
- スレッド生成のコスト削減.
- ピーク時の負荷(またはリソース消費量)制御.
- スレッドプールを使用すべきである.
- Apache JServ 1.1の設定
- スレッドプールの使用…jserv.propertiesで"pool=true"と設定する.
- スレッドプールの最大値の指定…jserv.propertiesで"pool.capacity=最大スレッド数"と設定する (デフォルト: 10).
- Tomcat 3.1の設定
- スレッドプールの使用…server.xmlのConnector要素のclassNameにorg.apache.tomcat.service.SimpleTcpConnectorクラスの代りにorg.apache.tomcat.service.PoolTcpConnectorクラスを指定する.
- スレッドプールの一時的な使用停止…<Parameter name="thread_pool" value="off"/>
- 最大スレッド数の設定…<Parameter name="max_threads" value="最大スレッド数"/> (デフォルト: 50)
- 最大待機スレッド数の設定…<Parameter name="max_spare_threads" value="最大待機スレッド数"/> (デフォルト: 25)
- 最小待機スレッド数の設定…<Parameter name="min_spare_threads" value="最小待機スレッド数"/> (デフォルト: 10)
ServerSocketのバックログ
- バックログ = listen()関数で指定するキューのサイズ.
- 並行処理リクエスト数が多い場合には増やしておくとよい.
- JDKのデフォルト値 = 50.
- Apache JServ 1.1の設定
- jserv.propertiesで,"security.backlog=バックログ数"と指定する (デフォルト = 5).
- Tomcat 3.1の設定
- org.apache.tomcat.service.SimpleTcpConnectorクラスは設定不可 (デフォルト = 100)
- org.apache.tomcat.service.PoolTcpConnectorクラスは,server.xmlのConnecter要素で,<Parameter name="backlog" value="バックログ数"/>と指定する.(デフォルト = 100)
Servletのオートリロード
- あるservletにアクセスがあった時に,クラスファイルが更新されていた場合に,servletをアンロードしてから,再びロードする機能
- servletにアクセスがある度にチェックするので計算コストが高い
- オートリロードは,必ずしも正しくおこなわれるとは限らない.
- オートリロードは,ヒープのフラグメンテーションを引き起こす可能性がある.
- オートリロードは開発時に留め,実運用では使わない方がよい.
- Apache JServ 1.1の設定
- zone.propertiesで"autoreload.file=false"と設定する.
- Tomcat 3.1の設定
- server.xmlのContext要素でreloadable="false"と設定する.
Servletコンテナへの通信のタイムアウト
- 異常リクエストが入った時に中断できる.
- 短すぎると正常リクエストが強制終了されるので注意する.
- Apache JServ 1.1の設定
- jserv.confで,"ApJServVMTimeout 秒数"と設定する(デフォルト: 10秒).
- デフォルト値が短いのに注意する.
- Tomcat 3.1の設定 (未確認)
- tomcat.confで,"ApJServVMTimeout 秒数"と設定する(デフォルト: 10秒).
- デフォルト値が短いのに注意する.
並行処理数の増大
- 同時に多くのリクエストを処理しなければならないシステムの場合には,並行処理数を増やすために,いくつかの対策が必要である.
- OSのファイル記述子の最大数を増やす
- プロセス外Servletコンテナは,ファイル記述子をより多く消費するので注意が必要である.
- Webサーバ・Servletコンテナのパラメタを増やす.
- selectシステムコールの問題
- selectは,同時接続数が多くなるほど遅くなる (同時接続数1000程度が目安).
- select()でなくpoll()を使用して実装されているJava VMが良い.
- Solaris用のProduction Releaseには,Pollerクラスの実装が含まれている.
- ネイティブメソッドを含む
- poll()と/dev/pollの両方をサポート(poll()がデフォルト)
- poll()に関しては,OSのバージョンによってチューニングレベルが異なるので,新しいバージョンが望ましい
並行処理リクエスト数の制御
- ある程度計算コストが掛かるシステムの場合,並行処理リクエスト数の制御が必要である.
- リクエストが一時的に集中した時に,それを遅延させることで負荷を平滑化できる
- 根本的にリクエスト数が多い場合には適さない
- Webサーバレベル: 最大クライアント数
- 通常はServletコンテナの方がボトルネックになるので,直接的に制御できない
- HTMLファイルの処理も制限されてしまう
- Servletコンテナレベル
- Servletレベル
- 計数セマフォ(counting semaphore)を使用し,並行処理リクエスト数の上限を決定する.
- 上限を越えたリクエストは待機させる.
- 待機スレッド数が増えすぎた時にはエラーメッセージを表示するのもよい.