一般的なWebサイトでは,アクセス集中時のシステム・ダウンを防ぐため,ロード・バランサで同時接続数の最大値を設定することがある。しきい値を超えたら,別に用意している「ただいま混雑しております」という画面を表示し,リソースにかかる過剰な負荷を軽減するのである。筆者はこれを「Sorry画面方式」と呼んでいる(図1)。

図1●Sorry画面方式
図1●Sorry画面方式

 Webサイトの入り口で流量を絞り,サーバーが想定以上の負荷を受け付けなくする手段としてはお手軽な仕組みであるが,サイトで提供しているサービスの特性をよく考えずに安易に使用すると問題が起きる。特にECサイトでは,この方式を安易に採用してはいけない。

 情報系サイトでは利用者に対する一方的な情報の伝達がメインであるのに対し,ECサイトでは利用者とサイト間の取引がメインとなる。たいていの場合,画面操作のどこかに「発注」や「支払い」が入る。利用者は単に画面の情報を参照するだけではなく,自らが当事者となって金銭をやり取りするわけだ。銀行の振込みや株式の売買,航空券の予約の場合だとその金額も結構なものとなる。最後に「確定」ボタンをクリックする際は,どうしても緊張してしまう。こういうときに,いきなりSorry画面に飛ばされたらどう感じるだろう?

 このタイミングでのSorry画面表示は,まず間違いなく利用者を混乱させる。自分がクリックした「確定」の結果が不明となり,いったい注文は本当に成立したのか,振り込みが成功したのか失敗したのか,疑心暗鬼に陥った利用者は,結果を参照する画面を繰り返しクリックし始める。

 Sorry画面が出たということは,「確定」を押したときにたまたま運悪くアクセスが集中していたということである。そして,この疑心暗鬼に陥った利用者によるパニック的なクリックがアクセスをさらに増大させ,ますますSorry画面が表示されることになる。いったんこの状態に陥ると,なかなか回復しない。

ロード・バランサに頼らず流量制限する

 では,どうすればよいのだろう?まず,単純にロード・バランサでの流量制限を行わない場合を考えてみる。この場合,Webサーバーはアクセスを基本的にすべて受け付ける。アクセスが集中すればリクエストがキューイングされ,利用者には「遅い」という現象として映る。

 だが,注文や支払いの確定を行っている状況下では,多少待たされてイライラはするものの,結果がきちんと出る方が最終的には安心する。「確認」ボタンをクリックする画面に,最後の処理なので時間がかかる旨を書いておけば,利用者が待ってくれる可能性も一段とアップする。結果として,Sorry画面方式よりもラッシュ状態から早く回復できることになるのだ。

 ただ,これだけだと,過負荷によるシステム・ダウンのリスクが解消されない。そこで,次にロード・バランサに頼らずに,どのような流量制御が可能か考えてみよう。システムを設計する側から見れば,流量制御したい理由はシステム・ダウンの防止,すなわちCPU/メモリーなどのリソースあふれの防止である。リソースを消費するのはプロセスやスレッドなので,Webサーバーやアプリケーション・サーバーで業務処理を実行しているアプリケーション・スレッドについてスレッド・プールの同時実行数の制限を設ける(図2)。たいていのWebサーバー/アプリケーション・サーバーでこの設定が行えるはずだ。ここでは,この方式を「スレッド制限方式」と呼ぶ。

図2●スレッド・プール制限方式
図2●スレッド・プール制限方式

 次に,リクエストを受け付けるキューのサイズを長くする。キューが短いと,アクセス集中時にすぐにキューがあふれてしまい,ブラウザに直ちにエラー画面が表示されることになる。メモリー容量が許す限り長めにしておこう。さらに,TCPのコネクションを多数同時に作成できるように,ファイル・ディスクリプタの上限値も引き上げるというOSパラメタ変更の設計もやっておく。処理によっては,TCPのコネクションを張るたびに複数のファイル・ディスクリプタの割り当てが必要になることもある。

 このように設計上の考慮をしておけば,同時に大量のアクセスが発生した場合でも基本的にリクエストを受け付けつつ,Webサーバーやアプリケーション・サーバーをダウンさせずに稼働させられるシステムとなる。可能であれば,画面の中でも商品検索や情報提供をメインとする参照系画面を処理するサーバーと注文/確認といった更新系画面を処理するサーバーを分離し,前者はSorry画面方式,後者は本コラムの方式というように併用すると,利用者の利便性をさらに高めることができるだろう。

 なお,ロード・バランサを使用する際はWebサーバー/アプリケーション・サーバーのヘルスチェック(稼働状態の確認)用のスレッド・プールとアプリケーション・スレッド用のスレッド・プールを同一に「してはいけない」(図3)。同一にした場合はアプリケーション・スレッドが満杯になった時点でサーバーのヘルスチェックが応答不能になって,どんなにサーバー側のリソースに余裕があったとしてもロード・バランサが当該サーバーを障害と見なして切り離してしまうからだ。スレッド・プール制限方式を活用する際の大前提とも言えるので,スレッド・プールはキューとセットでアプリケーション・スレッド用のものとヘルスチェック用のものを別々に設けるよう,注意しなければならない。

図3●ロードバランサを利用する際の注意点
図3●ロードバランサを利用する際の注意点

田代太一
野村総合研究所
基盤サービス事業本部 システム基盤統括二部
 97年,NRI入社。保険・流通・証券系の基幹業務システムの基盤方式設計・構築に従事し,特にWeb系技術を専門とする。2004年,米ミシガン大学に留学し,MBAを取得。現在は基盤PM兼チーフITアーキテクトとして証券系のASP事業開発に携わっている