1台サーバでFastCGIアプリをダウンタイム無く更新する方法について

なんか難しく考えていたけど実に単純な方法で出来るような気がしたのでメモ。


アプリ(fcgi_app.psgi)

#!/usr/bin/env plackup -s FCGI
use Plack::Handler::FCGI;

my $app = sub {
     return [
        200,
        [ 'Content-Type' => 'text/html' ],
        [ 'BEFORE' ]
    ];
};

my $server = Plack::Handler::FCGI->new(
    nporc  => 3,
    listen  => [ '/tmp/fcgi.sock' ],
    pidfile => '/tmp/fcgi.pid',
    detach => 1,
);

$server->run( $app );

nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    server {
        location / {
               set $script "";
               set $path_info $uri;
               fastcgi_pass   unix:/tmp/fcgi.sock;
        }
    }
}


1 アプリ起動

$ ./fcgi_app.psgi

2 nginx起動

$ sudo nginx

3 アプリを更新、ソケット名、PIDファイル名を変更

#!/usr/bin/env plackup -s FCGI
use Plack::Handler::FCGI;

my $app = sub {
     return [
        200,
        [ 'Content-Type' => 'text/html' ],
        [ 'AFTER' ] # BEFORE => AFTER
    ];
};

my $server = Plack::Handler::FCGI->new(
    nporc  => 3,
    listen  => [ '/tmp/fcgi2.sock' ], # fcgi.sock => fcgi2.sock
    pidfile => '/tmp/fcgi2.pid', # fcgi.pid => fcgi2.pid
    detach => 1,
);

$server->run( $app );

4 更新後のアプリを起動

$ ./fcgi_app.psgi

$ ls /tmp | grep fcgi
fcgi.pid
fcgi.sock
fcgi2.pid
fcgi2.sock

5 nginx.confのfasctcgi_passをfcgi2.sockを見るように更新

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    server {
        location / {
               set $script "";
               set $path_info $uri;
               fastcgi_pass   unix:/tmp/fcgi2.sock;
        }
    }
}

6 nginx再起動

$ sudo nginx -s reload

7 更新前のプロセスを終了

$ kill `cat fcgi.pid`

多分これでいけるのでは。