-
Notifications
You must be signed in to change notification settings - Fork 4
ELBのEC2のOut of Serviceへの移行について調査
mechamogera edited this page Nov 15, 2012
·
19 revisions
- 2012/11/07までの実験結果で考察してみる。
- ELBとして紐づくインスタンスが以下のような状態であるときは記述したような挙動になるようである。
- Out of Service:リクエストを投げない(他の生きているインスタンスにリクエストを投げる)
- In Serviceでコネクションが確立できない場合(サーバ停止中など):リクエストを投げない(他の生きているインスタンスにリクエストを投げる)
- In Serviceでコネクションが確立できる場合:リクエストを投げる
- In ServiceからOut of Servie(もしくはELB管理外)移行時に存在するコネクションは切断され、他の生きているインスタンスがある場合は再度リクエストがそのインスタンスに行くようである。
- ELBに紐付いたEC2インスタンスのサーバーを停止させてOut of Serviceにする
- 結果:生きてるインスタンスにリクエストがいくようになる
- 間違いっぽい(httpdがセッションを切ったためにエラー発生?) =>:サーバーが停止してOut of Serviceと判断されるまでリクエストが飛んでエラーとなる期間がある
- EC2インスタンス1準備(Amazon Linux)
- httpd導入
$ sudo yum install -y httpd
- httpdファイル配置
$ echo a | sudo tee /var/www/html/index.html
$ sudo touch /var/www/html/ping
- httpd起動
$ 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
- ELBを作成して作成したインスタンスを紐付け
- クライアントから以下のrubyスクリプトを実施
require 'rest-client'
while true
begin
res = RestClient.get( 'http://[ELBのドメイン名]/index.html' )
puts res.body
rescue => e
p e.message
end
end
- EC2インスタンス1でhttpdを停止
$ 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が続く
- EC2インスタンスがIn Service状態でApacheが停止している場合の挙動を調べる
- 結果:コネクションがはれない場合は生きているインスタンスに自動的にリクエストを送るようである
- 実験1と同じ、ただし、ELBのヘルスチェック間隔、回数を長めにとっておく
- EC2インスタンス1でhttpdをgracefulで停止
$ sudo apachectl graceful-stop
- EC2インスタンス1がIn Service状態の場合に任意のタイミングでELBにアクセスしてみる
$ curl http://[ELBのドメイン名]/index.html
- curlでは取得した結果がbとなる、失敗はしない
- EC2インスタンスがIn Service状態でApacheが停止した時に存在したコネクションの挙動を調べる
- 結果:In Service状態であるうちはコネクションは維持される
- EC2インスタンス1準備(Amazon Linux)
- httpd導入
$ sudo yum install -y httpd
- httpdのcgiの設定
$ sudo vi /etc/httpd/conf/httpd.conf
AddHandler cgi-script .cgi # <= コメント外す
...
<Directory "/var/www/cgi-bin">
Options +ExecCGI # <= 追加
- cgiの作成
$ 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
- httpd起動
$ 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
- curlの結果はbが返ってくる
- ELBに紐付いたEC2インスタンスのhealth checkだけ失敗させてOut of Serviceにする
- 結果:サーバーが停止してOut of Serviceと判断されるまでリクエストが飛ぶがhealth check以外は正常なためエラーとならない
- 疑問:Out of Serviceと判断される前のセッションは切断される?
- 実験1と同じ
- 実験1と同じようにスクリプトを動かすが、EC2インスタンス1でhttpdを停止するのではなくhealth check用のファイルを取り除く
$ sudo mv /var/www/html/ping{,.bak}
- クライアントの出力が以下のようになった
# aとbが交互に
a
b
a
b
b
# bが続く
- ELBからインスタンスを外した場合に存在するコネクションがどうなるか調べる
- 結果:ELBからインスタンスを外す際にコネクションは切断されるようである
- 疑問:EC2インスタンスが2つある時は?
- 参考:AWS Developer Forums: Existing connections dropped rudely ...
- EC2インスタンス1準備(Amazon Linux)
- ELBのOutOfService時のセッション確認用 — Gistを使用
- ポート番号8080で/test(50秒待って200返す)、/ping(server.ymlの設定に従って200 or 503を返す)
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からインスタンスを外すといつまで待ってもクライアントにレスポンスが返ってこない
- ELBからインスタンスを外した場合に存在するコネクションがどうなるか調べる
- 結果:生きているインスタンスにリクエストが再度送られELBからそちらのレスポンスが返る
- EC2インスタンス1準備(Amazon Linux)
- ELBのOutOfService時のセッション確認用 — Gistを使用
- ポート番号8080で/test(50秒待って200返す)、/ping(server.ymlの設定に従って200 or 503を返す)
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では処理完了のログが出ている