実験結果より考察
- 2012/11/07までの実験結果で考察してみる。

- ELBとして紐づくインスタンスが以下のような状態であるときは記述したような挙動になるようである。
- Out of Service:リクエストを投げない(他の生きているインスタンスにリクエストを投げる)
- In Serviceでコネクションが確立できない場合(サーバ停止中など):リクエストを投げない(他の生きているインスタンスにリクエストを投げる)
- In Serviceでコネクションが確立できる場合:リクエストを投げる
- In ServiceからOut of Servie(もしくはELB管理外)移行時に存在するコネクションは切断され、他の生きているインスタンスがある場合は再度リクエストがそのインスタンスに行くようである。
実験1:ELBに紐付いたEC2インスタンスのサーバーを停止させてOut of Serviceにする
- ELBに紐付いたEC2インスタンスのサーバーを停止させてOut of Serviceにする
- 結果:生きてるインスタンスにリクエストがいくようになる
- 間違いっぽい(httpdがセッションを切ったためにエラー発生?) =>:サーバーが停止してOut of Serviceと判断されるまでリクエストが飛んでエラーとなる期間がある
前準備
- EC2インスタンス1準備(Amazon Linux)
- httpd導入
$ sudo yum install -y httpd
$ echo a | sudo tee /var/www/html/index.html
$ sudo touch /var/www/html/ping
$ sudo /etc/init.d/httpd start
- EC2インスタンス2準備(Amazon Linux)
- EC2インスタンス1と同様に準備
- ただし、httpdファイルは以下のように配置
$ echo b | sudo tee /var/www/html/index.html
$ sudo touch /var/www/html/ping
実験手順
require 'rest-client'
while true
begin
res = RestClient.get( 'http://[ELBのドメイン名]/index.html' )
puts res.body
rescue => e
p e.message
end
end
$ sudo /etc/init.d/httpd stop
- もしくは、EC2インスタンス1でhttpdをgracefulで停止
$ sudo apachectl graceful-stop
実験結果
- httpdを落とした場合クライアントの出力が以下のようになった
# aとbが交互に
a
b
a
b
"Server broke connection"
b
"Server broke connection"
b
"Server broke connection"
b
b
# bが続く
- httpdをgracefulに停止した場合クライアントの出力が以下のようになった
# aとbが交互に
a
b
a
b
b
b
# bが続く
実験1-2:ELBに紐付いたEC2インスタンスのサーバーをgracefulで停止させてOut of Serviceにした場合の挙動確認
- EC2インスタンスがIn Service状態でApacheが停止している場合の挙動を調べる
- 結果:コネクションがはれない場合は生きているインスタンスに自動的にリクエストを送るようである
前準備
- 実験1と同じ、ただし、ELBのヘルスチェック間隔、回数を長めにとっておく
実験手順
- EC2インスタンス1でhttpdをgracefulで停止
$ sudo apachectl graceful-stop
- EC2インスタンス1がIn Service状態の場合に任意のタイミングでELBにアクセスしてみる
$ curl http://[ELBのドメイン名]/index.html
実験結果
実験1-3:ELBに紐付いたEC2インスタンスのサーバーをgracefulで停止させた場合の存在するコネクションの挙動確認
- EC2インスタンスがIn Service状態でApacheが停止した時に存在したコネクションの挙動を調べる
- 結果:In Service状態であるうちはコネクションは維持される
前準備
- EC2インスタンス1準備(Amazon Linux)
- httpd導入
$ sudo yum install -y httpd
$ sudo vi /etc/httpd/conf/httpd.conf
AddHandler cgi-script .cgi # <= コメント外す
...
<Directory "/var/www/cgi-bin">
Options +ExecCGI # <= 追加
$ sudo vi /var/www/cgi-bin/test.cgi
#!/usr/bin/ruby
print "Content-type: text/html\n\n"
print "a"
$ sudo chmod 777 /var/www/cgi-bin/test.cgi
$ sudo /etc/init.d/httpd start
- EC2インスタンス2準備(Amazon Linux)
- インスタンス1と同じように設定、ただしcgiは以下の内容にする
#!/usr/bin/ruby
print "Content-type: text/html\n\n"
sleep 50
print "b"
- ELBに作成したインスタンスを紐付ける
- HealthCheckはOut of Serviceまでの時間が長くなるようにしておく
実験手順
$ curl http://[ELBのドメイン名]/cgi-bin/test.cgi
- レスポンスを待つようになったらインスタンス2のhttpdをgracefulに停止する
$ sudo apachectl graceful-stop
実験結果
実験2:ELBに紐付いたEC2インスタンスのhealth checkだけ失敗させてOut of Serviceにする
- ELBに紐付いたEC2インスタンスのhealth checkだけ失敗させてOut of Serviceにする
- 結果:サーバーが停止してOut of Serviceと判断されるまでリクエストが飛ぶがhealth check以外は正常なためエラーとならない
- 疑問:Out of Serviceと判断される前のセッションは切断される?
前準備
実験手順
- 実験1と同じようにスクリプトを動かすが、EC2インスタンス1でhttpdを停止するのではなくhealth check用のファイルを取り除く
$ sudo mv /var/www/html/ping{,.bak}
実験結果
# aとbが交互に
a
b
a
b
b
# bが続く
実験3:インスタンスが1台だけの時のOut Of Service移行時のコネクションについて調査
前準備
sudo yum update -y
sudo yum install -y git
git clone git://gist.github.com/4028794.git
cd 4028794
ruby server.rb
- ELBを作成する
- ELB:80 => EC2:8080にリクエストを送るようにする
- HealthCheckは/pingに対して行う
- 作成したインスタンスを紐付ける
実験手順
git clone git://gist.github.com/4028794.git
cd 4028794
ruby client.rb
- ELBのインスタンスを外す、もしくはhealthCheckのみを失敗するようにする
実験結果
- クライアントからのリクエスト中にELBからインスタンスを外すといつまで待ってもクライアントにレスポンスが返ってこない
実験4:インスタンスが2台の時のOut Of Service移行時のコネクションについて調査
- ELBからインスタンスを外した場合に存在するコネクションがどうなるか調べる
- 結果:生きているインスタンスにリクエストが再度送られELBからそちらのレスポンスが返る
前準備
sudo yum update -y
sudo yum install -y git
git clone git://gist.github.com/4028794.git
cd 4028794
ruby server.rb
- EC2インスタンス2準備(Amazon Linux)
- EC1と同じようにするがレスポンスとしてbを返すようにしておく
- ELBを作成する
- ELB:80 => EC2:8080にリクエストを送るようにする
- HealthCheckは/pingに対して行う
- 作成したインスタンスを紐付ける
実験手順
git clone git://gist.github.com/4028794.git
cd 4028794
ruby client.rb
- インスタンス1にリクエスト中にELBからインスタンス1を外す
実験結果
- レスポンスにインスタンス2からのレスポンスbが返ってくる
- レスポンス1では処理完了のログが出ている