Nedia What's up!

ネディアのエンジニアによるIT技術やサービスの紹介・検証などをお届け!

Nginxのロードバランシング機能を使ってみよう!②

前回の記事でNginxで出来るロードバランサーの種類と設定方法について紹介しました。
今回は、設定後の動作確認の仕方について紹介したいと思います。

構成

nginx2-04

①異なるコンテンツを使った確認方法

通常ロードバランサーを利用する場合、向け先の各アプリケーションサーバー内のコンテンツは同じにしますが、各アプリケーションサーバー内のコンテンツをあえて変えることでロードバランサーの動作確認を手軽に行うことが可能です。

AppServer01 の index.html

AppServer01に接続された場合の画面

nginx2-05

AppServer02 の index.html

AppServer02に接続された場合の画面

nginx2-06

ラウンドロビン設定時の動作
F5ボタン等でブラウザの再読み込みを行う度にほぼ同じ頻度でAppServer01とAppServer02が交互に表示されれば正常に動作していると判断出来ます。

IPハッシュ設定時の動作
最初に出た方のAppServerがその後も変わらずに連続して表示されます。接続元のIPを変えて再接続した後で、もう片方のAppServerが表示されれば、その後何度再読みしてそのAppServerが表示され続けるという動作になります。

②tcpdumpコマンドを使った確認方法

続いて紹介するのはtcpdumpコマンドを使った確認方法です。

tcpdumpはネットワーク上に流れるパケットをモニタリングすることが出来るコマンドとなりますが、オプションとして条件を指定することで、取得したい情報にフィルタリングしてパケットを取得することが可能です。

今回テストで利用するオプションの説明は下記の通りです。

host IPアドレス | ホスト名
フィルタリングの対象とするホストをIPアドレスまたはホスト名を指定する。

port ポート番号
フィルタリングの対象とするポート番号を指定する。

-n
IPアドレスやポート番号などを名前に変換せずに表示する。
IPアドレスなどを表示する際には通常,名前解決を行い解決した名前で表示するが、
このオプションを指定すると名前解決を行わず,IPアドレスやポート番号をそのまま表示する。

上記のコマンドをNginx,AppServerいずれかのサーバーで実行した状態で、ブラウザの再読み込みを数回行った結果がこちらとなります。(192.168.0.5はクライアントPCのIPアドレス)

■ラウンドロビンの結果

10:37:49.906361 IP 192.168.0.100.33312 > 192.168.0.202.http: Flags [S], seq 4033686563, win 14600, options [mss 1460,sackOK,TS val 55573197 ecr 0,nop,wscale 6], length 0
10:37:49.906896 IP 192.168.0.202.http > 192.168.0.100.33312: Flags [S.], seq 2530537250, ack 4033686564, win 14480, options [mss 1460,sackOK,TS val 55558501 ecr 55573197,nop,wscale 6], length 0

10:38:09.396982 IP 192.168.0.100.51038 > 192.168.0.201.http: Flags [S], seq 309849968, win 14600, options [mss 1460,sackOK,TS val 55592687 ecr 0,nop,wscale 6], length 0
10:38:09.397480 IP 192.168.0.201.http > 192.168.0.100.51038: Flags [S.], seq 2668702717, ack 309849969, win 14480, options [mss 1460,sackOK,TS val 55885950 ecr 55592687,nop,wscale 6], length 0

10:38:11.976884 IP 192.168.0.100.33316 > 192.168.0.202.http: Flags [S], seq 2053636128, win 14600, options [mss 1460,sackOK,TS val 55595267 ecr 0,nop,wscale 6], length 0
10:38:11.977401 IP 192.168.0.202.http > 192.168.0.100.33316: Flags [S.], seq 1126770700, ack 2053636129, win 14480, options [mss 1460,sackOK,TS val 55580571 ecr 55595267,nop,wscale 6], length 0

■IPハッシュの結果

10:32:20.992278 IP 192.168.0.100.http > 192.168.0.5.54298: Flags [P.], seq 3811:4192, ack 4588, win 413, length 381
10:32:20.995013 IP 192.168.0.202.http > 192.168.0.100.33284: Flags [.], ack 546, win 244, options [nop,nop,TS val 55229589 ecr 55244283], length 0

10:33:00.171853 IP 192.168.0.100.http > 192.168.0.5.54298: Flags [P.], seq 4954:5335, ack 5839, win 463, length 381
10:33:00.171967 IP 192.168.0.202.http > 192.168.0.100.33290: Flags [.], ack 546, win 244, options [nop,nop,TS val 55268766 ecr 55283462], length 0

10:33:41.227970 IP 192.168.0.100.http > 192.168.0.5.54298: Flags [P.], seq 6859:7240, ack 7924, win 547, length 381
10:33:41.229270 IP 192.168.0.202.http > 192.168.0.100.33300: Flags [F.], seq 358, ack 546, win 244, options [nop,nop,TS val 55309823 ecr 55324518], length 0

ラウンドロビン が接続の度に2つのAppServerのどちらかと通信を行っているのに対し、IPハッシュは初めに接続した片方のAppServerとしか通信を行っていないことが分かります。

③Apache Bench を使った確認方法

最後にこれまでの方法では確認がしにくいLeast Connectedの動作確認の方法を紹介します。

Least Connectedはアクティブな接続数がもっとも少ないサーバーに割り当てる動作をしますが、下準備として以下のようなスクリプトを用意します。

AppServer01 の index.py の中身
コネクションを張りっぱなしにするために応答に時間がかかるスクリプトを用意します。

AppServer02 の index.py の中身
こちらは文字列を表示するだけの簡単なスクリプトです。

Apache Benchを使って動作確認を行います。

nオプション: 生成するリクエスト数を指定します
cオプション: 並列実行する数(コネクション数)を指定します

5ユーザが合計100回リクエストした場合のシミュレートした結果がこちらです。

■ラウンドロビンの結果

Concurrency Level: 5
Time taken for tests: 22.561 seconds
Complete requests: 100
Failed requests: 50
(Connect: 0, Receive: 0, Length: 50, Exceptions: 0)
Write errors: 0
Total transferred: 14970 bytes
HTML transferred: 1150 bytes
Requests per second: 4.43 [#/sec] (mean)
Time per request: 1128.050 [ms] (mean)
Time per request: 225.610 [ms] (mean, across all concurrent requests)
Transfer rate: 0.65 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 12 1024 1006.8 2016 2045
Waiting: 12 1024 1006.8 2016 2045
Total: 12 1024 1006.8 2016 2045

■Least Connectedの結果

Concurrency Level: 5
Time taken for tests: 2.088 seconds
Complete requests: 100
Failed requests: 3
(Connect: 0, Receive: 0, Length: 3, Exceptions: 0)
Write errors: 0
Total transferred: 14997 bytes
HTML transferred: 1197 bytes
Requests per second: 47.90 [#/sec] (mean)
Time per request: 104.387 [ms] (mean)
Time per request: 20.877 [ms] (mean, across all concurrent requests)
Transfer rate: 7.01 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 17 100 347.3 39 2066
Waiting: 17 100 347.3 39 2066
Total: 17 100 347.4 39 2067

・ラウンドロビンだと、50のFaild(100アクセス中50アクセス失敗、交互にアクセスするため)

・Least Connectedだと、3のFaild(同時アクセス5なので初回だけ)

ご覧のようにラウンドロビンとLeast Connectedとで大きく結果が変わりました。

ラウンドロビンの場合は、接続数は無視して交互にアクセスされた結果、AppServer01側に設置したスクリプトによってFailedも50となっています。

それに対し、Least Connectedの場合は、AppServer01側は設置したスクリプトの影響で応答に時間がかかり接続数が増えた状態が続きます。
その結果、接続数が増えたままにはならない、AppServer02側に接続回数が集中してFailedの値も3で済んだようです。

まとめ

Nginxで設定したロードバランサーの動作確認を3つ紹介しましたがいかがでしたでしょうか?
アプリケーションサーバーを2台用にそれぞれ異なるコンテンツを配置し、ブラウザの再読み込みをした場合、各ロードバランサーごとの動作をまとめると下記のとおりになります。

①ラウンドロビン
アプリケーションサーバ-へのリクエストはラウンドロビンの形式で分配されます
 →ページの再読み込みをする度に変わる。ほぼ同じ頻度。

②Least Connected
次のリクエストはアクティブな接続数がもっとも少ないサーバーに割り当てられます
 →ページの再読み込みをする度に変わる。同じ頻度ではなくバラツキあり。

③IPハッシュ
次のリクエストにどのサーバーが選択されるべきかを決めるためにハッシュ関数が使われます(クライアントのIPアドレスに基づく)
 →最初に表示された方のアプリケーションサーバーのコンテンツが表示され続ける。(クライアントのIPを変えるまで変わらない)

なお最後に紹介したApache Benchは設定したロードバランサーの性能を測る上でも利用出来ますので、色々と試してみると面白いかと思います。

それでは。