アプリケーションサーバーの負荷分散を考えて見ます。
セッション維持の話を考えると、話が複雑化するのでここではセッション維持の話は、脇に置いておきます。
Web三層構造とは
一般的に「Web三層構造」と呼ばれるものは以下の構造になります。
HTTP サーバー(Webサーバー) 、APサーバー(アプリケーションサーバー)、DBサーバーの3つからなります。
これらの要素は必ずしも別々のサーバーに分割されている必用はありません。以下のように HTTPサーバーと、APサーバーが一緒になっている例も考えられます。
また個人でテスト用にサーバーを立てるようなケースでは、以下のように全ての要素が一つのサーバーに入っているケースが殆どだと思います。
HTTPサーバー、APサーバー、DBサーバーは、通常 TCP通信経由でコミニケーションします。
これらの三要素を一つのサーバーにまとめた場合でも、自分自身のホスト名を使ってサーバー内で各要素がTCP通信するのが一般的だと思います。但しコンポーネントが同じサーバーにインストールされている場合は、TCP通信よりももっと高速な別の通信方法が使われるケースもあります。
Web三層構造のメリットは、Webサーバーを構成するコンポーネントを疎結合で分けて設計する事で、負荷に応じて必用なコンポーネント毎に「スケールアップ」、もしくは「スケールアウト」できる事だと思います。
APサーバーとは?
APサーバーのソフトウェアの代表的な例としては、Oracle 社の WebLogic、Apache Tomcat、IBM WAS(WebSphere Application Server)、RedHat JBoss 等があります。
APサーバ-は、サーバー上でプログラムを実行する仕組みの事です。 上記の例として上げた、WebLogic, Tomicat, WAS, JBoss は、Java EE (Enterprise Edition)で書かれたプログラムを動かすためのソフトウェア (APサーバー)です。
APサーバーとは、外部からリクエストを受けた時にそのサーバー上でプログラムを実行する仕組みを持ったサーバーを指すので、実行するプログラムが Java EE 以外でも、PHP、Ruby、Python 等、プログラムを実行する事ができるサーバーであれば AP サーバーと言えます。
例えばこのブログは、WordPress を使用していますが、各記事のデータは DBサーバーに格納されています。
WordPress は、PHP で作られており、ユーザーからリクエストを受けると、DBサーバーに格納されている記事データなどを読み出し HTML ページをリクエスト毎に生成しています。
一ページのリクエストでも、ページの本体を生成する PHP スクリプト、ヘッダー・フッターを生成する PHPスクリプト、DBからデータを呼び出すための PHP スクリプトなどたくさんのスクリプトが実行されています。
サーバー上に単純にインストールされた PHP のスクリプトは、サーバーにログインして実行しないと実行できません。
そのため、HTTPサーバーからリクエストを受け付けられるように、「インターフェイス」となるプログラムを PHPを実行するサーバーにインストールし、その「インターフェイス」経由で受け付けたリクエストを元に PHP プログラムを実行します。これも APサーバーの一つの形です。
明確なAPサーバーの規定は存在しないと思いますが、APサーバーが持っているべき基本機能としては、Wikipedia によると以下のように定義されています。
- プログラムの実行環境やデータベースへの接続機能の提供
- 複数の処理を連結するトランザクションの管理機能
- 業務処理の流れを制御するビジネスロジックの実装
HTTP + AP サーバーを並列に増やす
一番単純なのは、前段にLoad Balancer を立てて並行に「HTTP + App」を増やしていく事だと思います。
初期構成で「HTTP + App」が一つのサーバーに収まっていて(このケースは結構多いかと)、分割が面倒な場合はこの構成は結構簡単にできると思います。
AP サーバーのみを並列に増やす
AP サーバーを単純に並列に増やす
HTTP Server に Nginx を使用する場合は、Nginx 自体が Load Balancing 機能を持っており、ターゲットのサーバーをグループで指定できるので、以下のように構成できます。
AP サーバーを機能別に分割する
現在のアプリケーションサーバーの機能を分割して、/app1 /app2 のようにパス毎にアプリケーションを割り振る事もできます。HTTP Server の設定の中に、パス毎にアクセス先を割り振る設定を書きます。
アプリケーションが開発者別に分かれている時も、この方法が良いかもしれません。
最近では API のバージョンを /v1, /v2 の用にパスで分けるのをベストプラクティスにしている事もあるので、新しいバージョンの API をリリースする時は、新しいアプリケーションサーバ-を立てて・・・という方式だとこの方法が良いかもしれません。
AP サーバーの機能分割 + HTTPサーバーの並列化
アプリケーションを機能別に分割しておくと、その後、HTTPサーバーが配信する静的なコンテンツの負荷が増えてきた時や、セッション数が増えてきた時には、以下のように分割できるはずです。
さらに、App1 だけ負荷が増えてきた場合は、App1 の前に Load Balancerを立ててそこだけ App1 サーバーを増やす事が出来ます。
上の図では、明示的に 「APP1」の前に 「Load Balancer」を書いていますが、Nginx であれば、upstream で、サーバーをグループ化したロードバランスができるので明示的 Load Balancerは必用無くなります(多分、他のHTTPサーバーも同じでは無いかと思う)
参考
- Nginxのロードバランシング機能を使ってみよう Nginx で upstream を使って、サーバーのロードバランシングをする。
- nginxで複数のWebアプリケーションのアクセスをパスで振り分けたい Nginx で各パス毎に別のアプリケーションサーバーを upstream で指定する。