Skip to content

ELBのEC2のOut of Serviceへの移行について調査

mechamogera edited this page Nov 7, 2012 · 19 revisions

実験結果より考察

  • 2012/11/07までの実験結果で考察してみる。 ELBから見たec2の状態遷移
  • 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
  • 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が続く

実験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

実験結果

  • curlでは取得した結果がbとなる、失敗はしない

実験2:ELBに紐付いたEC2インスタンスのhealth checkだけ失敗させてOut of Serviceにする

  • 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が続く

実験3:インスタンスが1台だけの時のOut Of Service移行時のコネクションについて調査

  • ELBからインスタンスを外した場合に存在するコネクションがどうなるか調べる
  • 結果:ELBからインスタンスを外す際にコネクションは切断されるようである
  • 疑問:EC2インスタンスが2つある時は?
  • 参考:AWS Developer Forums: Existing connections dropped rudely ...

前準備

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では処理完了のログが出ている
Clone this wiki locally