CLOUD NAVIクラウドとは?からクラウドを支える技術や関連用語まで解説

FJcloud実践

ロードバランサーでサーバーの負荷分散・可用性向上を実現する

2025年3月7日
ロードバランサーでサーバーの負荷分散・可用性向上を実現する

サーバーの前段に位置し、ユーザーからのアクセスを受け付け、背後のサーバーにアクセスを振り分ける装置を「ロードバランサー」と呼びます。今回はFJcloud-V上でロードバランサーを用い、複数サーバーへアクセスの分散を行う方法を紹介します。

ロードバランサーとは

1台のサーバーの能力には限界があるため、それ以上の負荷がかかると正常にサービスを提供できなくなってしまいます。またサーバーに障害が発生した場合、サーバーが1台しかないと、即座にサービスが停止してしまいます。そこでユーザー向けに提供しているサービスや、ある程度以上の規模を持つシステムでは、単体のサーバーを直接インターネットに公開することはせず、複数のサーバーを並列稼動させるのが定石です。

こうした構成において、サーバーの前段に位置し、ユーザーからのアクセスを受け付け、背後のサーバーにアクセスを振り分ける装置が「ロードバランサー」です。サーバーが複数並んでおり、かつ頻繁に増減すると、ユーザーはどこにアクセスしてよいか判断できません。ですがロードバランサーがアクセスを一手に引き受けることで、サービスに対する「エンドポイント」を提供できるというわけです。

「負荷(ロード)を平衡にする装置(バランサー)」はその名の通り、特定のサーバーに負荷が偏らないよう、アクセスを分散させることができます。ロードバランサーの背後に複数のサーバーを並べることで、システムはより高い負荷に耐えられるようになるというわけです。また背後のサーバーは都合に応じて任意に増減(スケール)させることができます。より柔軟にシステムを運用できるため、オンデマンドにインフラを調整できるクラウドと、非常に相性がよいシステムと言えるでしょう。

またサーバーが1台では、そこが単一障害点(SPoF)となってしまいます。ですがロードバランサーの背後に複数のサーバーを並べて冗長化しておけば、システムの可用性を上げることができます。また一般的なロードバランサーには、サーバーに対して常にヘルスチェックを行い、応答のないサーバーにはアクセスを振り分けないという機能が用意されています。このため万が一サーバーに障害が発生したとしても、ロードバランサーが自動的にシステムの健全性を保ってくれるのです。

ロードバランサーを導入することで可用性を高め、高負荷にも耐えられるシステムを作ることができます。FJcloud-Vには複数の種類のロードバランサーが用意されていますが、今回はTCP/IPレベルで分散を行う、ロードバランサー(L4)を例に紹介します。

サーバーとロードバランサーの構築

まずはUbuntu 22.04 LTSのインスタンスを2台起動します。

それぞれのサーバーにログインし、以下のコマンドでnginx Webサーバーをインストールしてください。

                        # apt update
# apt install -y nginx
                    

どちらのサーバーにアクセスしているか判断できるように、それぞれのサーバーで異なるindex.htmlを作成します[^1]。ここでは例として「server1」「server2」という文字列を書き込みました。

[^1]: 当然ですがこれは検証目的であり、本来はロードバランサー配下のサーバーに差異があってはいけないため、同じページをデプロイします。

# echo 'サーバー名' > /var/www/html/index.html

続いてコントロールパネルの「ネットワーク」→「ロードバランサー」を開き、「ロードバランサー作成」をクリックします。ロードバランサーの作成画面が開くので、必要な情報を入力してください。

「ロードバランサー名」は、文字通りロードバランサーにつける名前です。複数のLBを作る場合は区別しやすいよう、わかりやすい名前を入力しましょう。

「最大ネットワーク流量」は、同時にロードバランサーに流せるトラフィックの上限です。複数コネクションの合計となります。流量ごとに大きく料金が異なるため、要件に応じて選択してください。

「インターネットプロトコル」は、ロードバランサーのインターネットプロトコルです。IPv4とv6から選択できます。

「料金プラン」は、月額と従量課金から選択できます。

「ロードバランス方式」は、ロードバランサーがサーバーにアクセスを振り分ける方式です。順次割り振る「Round-Robin」と、接続数の少ないサーバーに割り振る「Least-Connection」から選択できます。ここではわかりやすい例として「Round-Robin」を選択しています。

「ポート設定」は、ロードバランサーが待ち受けるポートと、割り振る先のサーバーのポートの設定です。今回はWebサーバーを利用してテストを行いますので、TCPの80番ポートを設定しています。

「PINGプロトコル」は、ロードバランサーがサーバーのヘルスチェックを行う際のプロトコルです。ここではTCPを指定しています。

「ヘルスチェック間隔」は、ロードバランサーがヘルスチェックを行うインターバルです。デフォルトは30秒です。

「タイムアウトまでのヘルスチェック回数」は、ロードバランサーが、そのサーバーがオフラインであると判断し、切り離すまでに試行するヘルスチェックの回数です。デフォルトは3回です。

「サーバー設定へ」をクリックすると、以下の画面に遷移します。

ここではロードバランサーがアクセスを割り振るサーバーを指定します。既に起動している2台のインスタンスが表示されますので、それぞれにチェックを入れてください。完了したら「フィルター設定へ」をクリックします。

ここではロードバランサーに対して、IPアドレスベースによるアクセス制限を設定できます。今回は特に制限を行わないため、何もせず「オプション設定へ」をクリックします。

ここではロードバランサーに紐づけるSSL証明書や、セッション固定やSorryページの設定が行えます。セッション固定とSorryページについては後述しますので、ここでは何もせず「確認へ」をクリックします。

最後に、作成するロードバランサーの設定が表示されます。問題ないことを確認したら「作成する」をクリックしてください。

アクセスの分散を確認する

ロードバランサーが作成されると、以下のようにIPアドレスが割り当てられます。このIPアドレスにWebブラウザーからアクセスしてみましょう。

ロードバランサーを経由して、背後にあるserver1のindex.htmlが表示されました。問題なくアクセスができているようです。

本当にアクセスは分散されるのでしょうか。連続して何度もアクセスし、分散されることを確認してみましょう。手元のPCから、以下のコマンドを実行してください。curlコマンドを用いて、1秒置きにロードバランサーにアクセスします[^2]。

[^2]: 無限にアクセスし続けます。終了するにはCtrl+Cキーを押して中断してください。

$ while true
    do
        curl http://ロードバランサーのIPアドレス/
        sleep 1
    done

概ね交互に、server1とserver2にアクセスしていることが確認できました。

スティッキーセッションとは

前述のようにロードバランサーを使えば、各サーバーの負荷が均等になるように、アクセスを振り分けることができます。ですがこれは言いかえると、リクエストの度に、実際に接続されるサーバーが変化する可能性があるということです。ステートレスなアプリケーションであれば、この挙動でも構いません。ですがセッション情報をアプリ側で保持しているようなケースでは、接続先のサーバーを固定できないと困ります。これを実現するのが「セッション固定(スティッキーセッション)」です。

ロードバランサーにスティッキーセッションを設定すると、一定時間内の同一IPアドレスからのアクセスは、常に同じサーバーに振り分けるようになります。試してみましょう。先ほど作成したロードバランサーを選択し、「オプション設定変更」を実行します。

「セッション固定」を「有効にする」に変更してください。セッション保持時間は3分から60分の間で自由に設定ができますが、今回はデフォルトの3分としています。

この状態で、先ほどと同様にコマンドを使い、連続してロードバランサーにアクセスしてみましょう、今度は常に同じサーバーに振り分けられていることがわかります。

ロードバランサーを使った可用性の向上

サーバーは、予期せぬ障害によってダウンしてしまう可能性があります。そこで複数のサーバーを並べて「冗長化」することで、サービスの可用性を向上させるのが原則です。ロードバランサーを使えば、簡単にサーバーの並列稼動を実現できるのは、これまでに述べてきた通りです。

ですがダウンしたサーバーに対して、アクセスが振り分けられてしまっては困ります。そこでロードバランサーにはヘルスチェック機能と、ヘルスチェックに合格しなかったサーバーを切り離す機能が用意されています。試してみましょう。

まず2台のサーバーのうち、1台をシャットダウンしてください。今回作成したロードバランサーのヘルスチェックは30秒間隔で、タイムアウトは3回ですから、その状態で90秒ほど待機します。するとロードバランサーの「ヘルスチェック」欄が「異常」となります。

ヘルスチェックに失敗したサーバー(ここではserver2)は、ロードバランサーから一時的に切り離され、アクセスの振り分け対象から外されます。そのため停止したサーバーにアクセスしてしまい、結果としてサービスがエラーとなるといった事態を防げるのです。

通常あってはならないことですが、配下のサーバーがすべてダウンしてしまったらどうなるのでしょうか。試しにもう1台のサーバーもシャットダウンしてみましょう。

この状態でロードバランサーのIPアドレスにアクセスすると、当然振り分け先のサーバーが全滅しているため、Webブラウザーがエラーを表示して停止します。

そこでSorryページを設定しましょう。先ほどと同様に、ロードバランサーの「オプション設定変更」から、「Sorryページ」を「有効にする」に変更します。すると背後のサーバーがすべてダウンしている状態でも、ロードバランサーが独自に、以下のような応答を返せます。

大規模な障害が発生してしまった際でも、接続できずエラーとなってしまうのではなく、最低限のメッセージをユーザーに返せるのは重要です。エンドユーザーがアクセスするサイトであれば、Sorryページは有効にしておくのがよいでしょう。

なお、ロードバランサーそのものに障害が発生する可能性を心配するかもしれませんが、FJcloud-VのL4ロードバランサーも、内部的に冗長化が行われています。

オートスケールの活用

ロードバランサーは、配下に複数のサーバーを配置し、負荷を分散できます。これはオンデマンドにサーバーの増減が可能なクラウドと、非常に相性がよい機能だと言えるでしょう。

クラウドのメリットのひとつに、必要な時に必要なリソースを確保する(あるいは開放する)ことで、費用の最適化がしやすい点があります。負荷に合わせてサーバーの台数を増減させる「オートスケール」とロードバランサーを組み合わせることで、負荷が増大したらサーバーを自動的に増やし、システムダウンによる機会損失を回避したり、逆に負荷が減る時間帯はサーバーを減らし、費用を抑えるといった柔軟な構成が可能になるのです。

オートスケールは、事前に登録しておいたサーバーのカスタマイズイメージをベースに、自動的にインスタンスを起動します。オートスケールについて詳しくは、技術仕様を確認してください。

ロードバランサーを活用したシステムを構築するには

ロードバランサーを使うことで、複数台のサーバーの並列稼動が容易になります。サービスの拡大にともなう高負荷対策はもちろん、小規模なサービスであっても、可用性向上のために2台以上のサーバーとロードバランサーを使うのもお勧めです。これはサーバー冗長化パターンとして、クラウドにおける設計の定石となっています。

ですがこうしたクラウドならではの設計を行うのであれば、サーバー側にも気を配る必要があります。例えば実際にアクセスがあるまで、どのサーバーにアクセスが振り分けられるかわかりません。そのためロードバランサー配下のサーバーは、すべてが等価である必要があります。それぞれのサーバーが「異なる個別の状態」を持っていると、サービスは正しく動かないでしょう。

そのため「サーバー内部にはデータを保持しない」「データベースやストレージは外部に出す」といった設計が必要となります。また高負荷対策としてスケールアウトを行うのであれば、起動したサーバーは自律的に初期化を行うべきです。従来のオンプレミスのサーバーのように、SSHで個別にログインして、手作業で設定を行うなどは避けましょう。cloud-initの起動スクリプトなどを使うことも検討してください。

PageTop