echoでgraceful restart
ちょろっとググっても見つからなかったので書いておく。
分かってると思うけど、golangのWAFのechoです。
go-server-starterを使う
使い方は下記の記事を参考にした。
net/httpをそのまま使うのであれば、上記の記事の通りに使えば完了なのだが、echoの場合、go-server-starter/listenerを使って得られるnet.Listenerインターフェイスの(実装)インスタンスをどこに差し込むのかという話になる。
まあ、echoのgodoc読めばすぐ分かるんだけどもね
type Echo struct { Server *http.Server TLSServer *http.Server Listener net.Listener TLSListener net.Listener AutoTLSManager autocert.Manager DisableHTTP2 bool Debug bool HideBanner bool HTTPErrorHandler HTTPErrorHandler Binder Binder Validator Validator Renderer Renderer // Mutex sync.RWMutex Logger Logger // contains filtered or unexported fields }
と、上記のようにEcho構造体のメンバ、Listenerは外部から差し替えられるので、そこに差し込めばよい
e.Listener = l
という感じに
(もちろんeはEcho構造体のインスタンスで、lはnet.Listenerのインスタンス)
あとは、公式cookbookのgraceful shutdownのページにある通りにすればよい
注意点として、net.Listenerにすでにポート番号を指定しているので、echoサーバを開始するときにはポート番号を指定しないようにすること。(上記のリンク中では指定している)
e.start("")
のように空文字を指定する。
あとは、ビルドしてできたバイナリをstart_serverコマンド経由で起動する。
start_serverコマンドは本家のperl版のServer::Starterと同じなので適当にググって
簡単な例だと以下のような感じ(appはechoで作ったサーバのバイナリ名として)
start_server --port="任意のポート番号" --pid-file=/tmp/app.pid --status-file=/tmp/app.status -- app
pid-fileとstatus-fileのpathも任意です。
そして、supervisorとかでstart_serverプロセスを管理する。
graceful restartさせたい場合、start_serverのプロセスにHUPシグナルを発行するか、以下のようにする。
start_server --pid-file=/tmp/app.pid --status-file=/tmp/app.status --restart
pid-fileとstatus-fileのパスは、プロセスを立ち上げたときに指定したのと同じものを指定する。
facebook/graceとかじゃダメなん?
echoの公式でもfacebook/graceを使っていたので、これでいんじゃね?と思ったのだけど、facebook/graceだとプロセスIDが変わってしまうのだとか?
supervisorで管理したかったので、それは避けたかった
Server::Starterの場合、supervisorで直接管理するのはstart_serverプロセスで、greceful restartしたい対象のプロセスはstart_serverプロセスが管理するような形になる。
start_server管理下のプロセスはgraceful restartでプロセスIDが変わる(というか新規に立ち上げる)のだけど、start_serverプロセスのプロセスID自体は変わらないので、そのままsupervisorで管理できる。