【基礎から学ぶ】ELBのスティッキーセッションについてまとめてみた

記事タイトルとURLをコピーする

はじめに

こんにちは、技術3課の紅林です。年始早々に風邪を引いてしまい、なかなか辛い正月を過ごすことになってしまいました。
今回、AWSのElastic Load BalancingClassic Load Balancer (以下、ELB)のスティッキーセッション機能についてまとめてみました。
目次は以下の通りとなります。

ELBのスティッキーセッション、その前に

ELBのスティッキーセッションの前に、その前提となるCookieとセッションについて概要をおさらいしてみます。

Cookieについて

CookieはRFC6265によって標準化されているWebサーバがクライアント(ブラウザ)に一時的にデータを保存させる仕組みです。サーバはこの情報を使うことにより、ユーザ識別やセッション管理を実現出来ます。 主な動作概要としては以下のようになります。

  • サーバはSet-Cookieヘッダの利用によりCookieをクライアントに渡します
  • クライアントは同じサーバにリクエストを送る際、そのサーバから渡されたCookieの情報を渡すことにより、サーバはその情報に基づいた処理を行います
Cookieの動作例

Cookieの動作を具体的に確認してみます。

テストコード
<?php 
    if (isset($_COOKIE["kure"])){
        $count = $_COOKIE["kure"] + 1;
    }else{
        $count = 1;
    }
    setcookie("kure", $count);
    print('訪問回数は'.$count.'回目です');
?>
動作概要

動作概要は以下の通りとなります。

  • サーバへの初回のリクエストは、クライアントにCookieが保存されていないため、Cookieの送信はありません
  • サーバはレスポンスで、Set-Cookieヘッダを利用し、Cookie(kure=1)をクライアントに渡します
  • クライアントは2回目以降のリクエストで、送信されたCookie情報を格納してサーバに送信します
  • サーバはレスポンスで、Set-Cookieヘッダを利用し、インクリメントした値(kure=2)をCookieに格納し、クライアントに渡します

シーケンス図

cookie

動作結果

1回目アクセス

f:id:cmpokuma:20200508143212p:plain

2回目アクセス

f:id:cmpokuma:20200508143600p:plain

3回目アクセス

f:id:cmpokuma:20200508143712p:plain

パケットキャプチャ

1回目アクセス(サーバ→クライアント)

f:id:cmpokuma:20200508143855p:plain

2回目アクセス(クライアント→サーバ)

f:id:cmpokuma:20200508144001p:plain

3回目アクセス(サーバ→クライアント)

f:id:cmpokuma:20200508144056p:plain

セッションについて

Cookieの利用により、セッション維持を実現できます。以下、動作の概要となります。

  • 初回アクセス時、サーバはクライアント毎に異なるセッションID生成し、その情報をSet-Cookieヘッダを利用しクライアントに送信します
  • 次回以降アクセス時、クライアントはセッションID情報をCookieに格納し、サーバに送信します
  • サーバは送信されたセッションIDを確認し、クライアント毎の情報(例えば、ショッピングサイトであれば、クライアントとカートに入れた商品の紐付け等)を処理し、返信します
    • クライアント毎の情報(例えば、ショッピングサイトであれば、クライアントとカートに入れた商品の紐付け等)自体はサーバ側に保存します

f:id:cmpokuma:20200508144612p:plain

ELBのスティッキーセッションについて

概要

ELBのスティッキーセッションはELBがサーバにリクエスト振り分ける際、特定のCookieを確認することで、特定のクライアントからのリクエストを特定のサーバに紐付けることが出来る機能です。 ELBのスティッキーセッションの設定は以下3つのパターンが選択出来ますので、それぞれどのような動作となるか確認してみます。

  • 維持無し
  • ELBによって生成されたCookieの維持
  • アプリケーションによって生成されたCookieの維持
検証構成概要

ELBにサーバを2台ぶら下げた形でクライアントからリクエストを送信し、どのような動作をするか確認します。

elb構成

コード

以下のコードのファイルをそれぞれのサーバに設置します。 「ip-x-x-x-x」の部分にはそれぞれのサーバのプライベートIPアドレスを記載するようにします。
いずれかのサーバにアクセスすると、
「ip-x-x-x 訪問回数:N」
が表示されます。

<?php
session_start();
?>

<html>
<head><title>PHP TEST</title></head>
<body>
ip-x-x-x-x
<?php
if (!isset($_SESSION["visited"])){
        print('初回の訪問です');
        $_SESSION["visited"] = 1;
}else{
        $visited = $_SESSION["visited"];
        $visited++;
        print('訪問回数:'.$visited);
        $_SESSION["visited"] = $visited;
}
?>
</body>
</html>

維持無し

スティッキーセッション無しの場合、リクエストはELBの負荷分散機能により、サーバに振り分けられます。したがって、リクエストの度に異なるサーバに振り分けられる可能性があるため、サーバでのセッション管理を前提としたシステムの場合は注意が必要です。
AWSのマネジメントコンソール上では、ELBの「維持設定の編集」から、以下の画面で「維持の無効化」を選択します。

f:id:cmpokuma:20200508150158p:plain

動作確認

以下、5回続けてアクセスしてみた結果です。それぞれのサーバに振り分けがなされていることが分かります。

1回目アクセス

f:id:cmpokuma:20200508150451p:plain

2回目アクセス

f:id:cmpokuma:20200508150608p:plain

3回目アクセス

f:id:cmpokuma:20200508150655p:plain

4回目アクセス

f:id:cmpokuma:20200508151437p:plain

5回目アクセス

f:id:cmpokuma:20200508151531p:plain

ELBによって生成されたCookieの維持

この方式では、ELBによって生成されるCookieによってリクエストの振り分けサーバが固定されます。返信のリクエストがELBを経由する際にCookieが付加されます。
AWSのマネジメントコンソール上では、ELBの「維持設定の編集」から、以下の画面で「ロードバランサーによって生成されたCookieの維持を有効化」を選択します。Cookieの有効期間の指定も出来ます。

f:id:cmpokuma:20200508151654p:plain

シーケンス図

シーケンス概要を以下に図示します。

f:id:cmpokuma:20200508152044p:plain

動作確認

動作確認してみると、維持機能無しの場合と違い、同じサーバにリクエストが振り分けられることが分かります。

アクセス1回目

f:id:cmpokuma:20200508152222p:plain

アクセス2日目

f:id:cmpokuma:20200508152320p:plain

アクセス3回目

f:id:cmpokuma:20200508152430p:plain

アプリケーションによって生成されたCookieの維持

この方式では、ELBでアプリケーションのCookie名を指定し、そのCookie情報をELBが確認して、振り分けるサーバが固定されます。
AWSのマネジメントコンソール上では、ELBの「維持設定の編集」から、以下の画面で「アプリケーションによって生成されたCookieの維持を有効化」を選択し、Cookie名を指定します。

f:id:cmpokuma:20200508154352p:plain

シーケンス図

シーケンス概要を以下に図示します。

f:id:cmpokuma:20200508154513p:plain

動作確認

これも、ELBによって生成されたCookieの維持機能と同様に同じサーバにリクエストが振り分けられます。

アクセス1回目

f:id:cmpokuma:20200508152222p:plain

アクセス2日目

f:id:cmpokuma:20200508152320p:plain

アクセス3回目

f:id:cmpokuma:20200508152430p:plain

注意点

注意点として、サーバ側でSSLの終端を行う場合は、スティッキーセッション機能を使うことはできません。HTTPSでHTTPヘッダが暗号化されるということもありますが、サーバ側でSSLを終端するため、リスナーをTCPで設定すると、AWSのマネジメントコンソール上からも以下のようにスティッキーセッションの設定を行うことが出来なくなります。

f:id:cmpokuma:20200508155402p:plain

おわりに

今回、ELBのスティッキーセッションについて、まとめてみました。乾燥する季節ですので、風邪には特に気をつけて、過ごしましょう。