5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Oracle Cloud] Load Balancer で Session Persistence をやってみた

Last updated at Posted at 2019-11-22

はじめに

Oracle Cloud Infrastructure(以下OCI) で提供している Load Balancer には、Session Persistence と呼ばれるバインド機能があります。
Session Persistence を使うことによって、Load Balancer にアクセスしてきたユーザーのリクエストを、前回アクセスしたバックエンドサーバーにバインドすることが可能です。
AWS の ELB でいうと、スティッキーセッションと似た機能となっています。

概要

  • 初めてアクセスしてきた client に、特定の値を持つ cookie を設定
  • 2回目以降のアクセスを行った時に、特定の値を持つ cookie を確認して、前回アクセスしたバックエンドサーバーへリクエストをバインドする

アプリケーションの構成によっては、前回アクセスしたサーバと同一なものへアクセスし続けることが必要になります。
例を挙げると、セッション管理をローカルで行う、ファイルをローカルに生成している、といったことが考えられます。

モダンなアプリケーションの構成では、こういったローカル管理はやめてステートレスにしていくことが望ましいですが、様々な理由からアプリケーションの変更が出来ない事も多いです。
このような時に、Session Persistence 機能を使うことで、便利に負荷分散していくことが可能です。

1574436977651.png

前提作業

OCI環境

以下の環境をすでに OCI で作成済みです。

  • Compute Instance 2台
    • CentOS7
  • Load Balancer

バックエンドサーバーで Cookie のログ出力

Session Persistence の機能自体を使用するには、特別な設定は バックエンドサーバーには不要です。
今回は、バックエンドサーバー側でどのような Cookie を受信したか確認したいので、Golang で Webサーバーを構成して、Cookie の内容を標準出力へ出力するプログラムを書きます。

Golang install は以下の記事を参考に適当に導入します
https://qiita.com/sugimount/items/1e677f1beab747959b81

Cookie の内容を標準出力へ出力するプログラムは、Github で公開しています
https://github.com/Sugi275/sample-go-cookie

ソースコードは以下の通りです。

package main

import (
	"fmt"
	"log"
	"net/http"
)

// cookieの設定+標準出力へプリント
func setCookies(w http.ResponseWriter, r *http.Request) {
	cookie := &http.Cookie{
		Name:  "hoge",
		Value: "bar",
	}
	http.SetCookie(w, cookie)

	fmt.Fprintf(w, "Hello Cookie!")

	cookies := r.Cookies()

	fmt.Println("start")
	fmt.Println(cookies)
	fmt.Println("end")
}

// メイン
func main() {
	http.HandleFunc("/", setCookies)

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

Golang をインストール済みの Linux 環境で、以下のように簡単に実行することができます。
OCI 上に作成した、Compute Instance 2台で以下のコマンドを実行します。

cd ~
git clone https://github.com/Sugi275/sample-go-cookie.git
cd ~/sample-go-cookie
./sample-go-cookie

上記を実行すると、8080番ポートで Webサーバーが立ち上がります。ブラウザを使用して、Compute Instance の Public IP にアクセスを行うと、以下のWebページが表示されます。
Chrome のデベロッパーツールで Cookies を表示すると、Golang 上で SetCookie した内容が確認できます。

1574437644282.png

Goのプログラム上で、Cookie の内容を標準出力へ出力した結果は、以下の内容が表示されています。

[opc@web01 sample-go-cookie]$ ./sample-go-cookie 
start 
[hoge=bar]
end

Session Persistence の設定

前提作業で構成した、OCI Load Balancer の詳細画面へ移動します。

1574438102958.png

Backend Sets の Edit を選択します。

1574438169793.png

ENABLE LOAD BALANCER COOKIE PERSISTENCE を選択して、Save Changes を押します。

選択肢の説明をします。

  • DISABLE SESSION PERSISTENCE : Session Persistence を無効にする
  • ENABLE APPLICATION COOKIE PERSISTENCE : バックエンドサーバー側で、Cookie を作成するオプション。細かな制御を行いたい場合はこちらを選択する
  • ENABLE LOAD BALANCER COOKIE PERSISTENCE : Load Balancer 側で、Cookie を作成するオプション。基本的にはこちらを使用すると思う。Cookie NAME や、Cookie の有効期間などを指定することが可能

1574438303304.png

Session Persistence 動作確認

アクセス確認

Load Balancer を経由して、バックエンドサーバーにアクセスして、Chrome の Developper Tools を確認します。
Session Persistence 時に、COOKIE NAME を空白にしたので、Default の X-Oracle-BMC-LBS-Route というName の Cookie が生成されています。Value は Load Balancer 側で生成されたランダムの値が入っています。
このランダムの値を使用して、どこのサーバーにバインドするべきかを管理されている動きになります。

1574438754889.png

Golang 側の標準出力を見ると、以下のような出力となっています。こちらの結果でも、X-Oracle-BMC-LBS-Route の Cookie を確認することが出来ます。
Web01 バックエンドサーバー側でも正しく、Load Balancer で自動付与された Cookie を確認することが出来ます。

[opc@web01 sample-go-cookie]$ ./sample-go-cookie  
start 
[X-Oracle-BMC-LBS-Route=cfc5eecb841cac84444ddf07c6db58e9b8ac77fc hoge=bar]
end

Cookie が Expire しない限り、何度アクセスしても前回アクセスしたバックエンドサーバーへバインドされます。

Cookie 削除して確認

Cookie を削除して、アクセス先のサーバーや、Cookie の値が変更することを確認します。

Chrome で、以下の黄色い箇所をクリックします

1574439866321.png

Cookie を選択します

1574439889016.png

削除して、完了を押します。

1574439970582.png

再度 Chrome からアクセスします。Value の値が先ほどと変わっています。

1574440114664.png

バックエンドサーバー側の標準出力を見ると、先ほどまでWeb01 でしたが、Web02 側に切り替わりました。

[opc@web02 sample-go-cookie]$ ./sample-go-cookie
start 
[X-Oracle-BMC-LBS-Route=bd28576df4f98e0ed1f460613b3a1a6a1f93a09b hoge=bar]
end

フェールオーバー動作確認

今は Web02 側でバインドされています。では、このときに、Web02側に障害がおこるとどうなるのでしょうか。
答えは、正常に動作しているWeb01 側にフェールオーバーします。この時に、Cookie も再度作成されます。

では、Web02 で動作している Golang を停止して、再度アクセスを行います。
以下の表示結果のように、Value がまた変わっています。

1574440298221.png

バックエンドサーバー側を確認すると、Web01 側で以下のログが表示されています。

[opc@web01 sample-go-cookie]$ ./sample-go-cookie
start 
[X-Oracle-BMC-LBS-Route=bd28576df4f98e0ed1f460613b3a1a6a1f93a09b hoge=bar]
end

参考URL

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?