nginx の Connection Draining

docker 化をすすめるにあたり、consul-templateregistratornginx の upstream を動的に更新しようと思いました。

ところで、

upstream backend {
  server 10.1.2.3:3456;
  server 10.1.2.4:4567;
  server 10.1.2.5:5678;
}

という状態から1つ減って

upstream backend {
  server 10.1.2.3:3456;
  server 10.1.2.4:4567;
}

となった場合、消えた 10.1.2.5:5678 とつながっていたクライアントとの通信はどうなるのでしょうか?

LoadBalancer には Connection Draining という機能・設定があります。
ELB にもあります(ロードバランサーの Connection Draining を設定する)。

nginx ではどうなるのか試してみました。version は 1.11.1

nginx で

upstream backend {
  server 127.0.0.1:8080;
  server 127.0.0.1:8081;
  server 127.0.0.1:8082;
  server 127.0.0.1:8083;
}

とし、Apache にてざっとこんな感じで 8080, 8081, 8082, 8083 で CGI が動くようにし、

Listen 8080
Listen 8081
Listen 8082
Listen 8083

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"


    AllowOverride None
    Options None
    Order allow,deny
    Allow from all













こんな CGI で各ポートに接続され、出力が流れている状態で nginx の upstream を減らして nginx -s reload すると通信が止まるかどうか

#!/usr/bin/perl
use strict;
use warnings;

$| = 1;

print "Content-Type: text/plain\n\n";

for my $i (0 .. 60) {
    printf "%3d %s\n", $i, $ENV{SERVER_PORT};
    sleep 1;
}

結果は「通信は途切れない」、もちろん新規の接続は upstream に残った proxy 先にのみ振られます。

良かった良かった、これで安心して思う存分コンテナの入れ替えができます。