https://christina04.hatenablog.com/entry/go-graceful-shutdown

概要

以前はGraceful shutdownをするために以下のようなライブラリを使用していました。

しかしながらGo 1.8 からGraceful Shutdown機能が標準で提供されるようになりました。 今回はその導入方法を紹介します。

環境

これまでの問題

例えば以下のような重い処理がHandlerにあるとします。 簡単のためsleepで実装しています。

func hello(w http.ResponseWriter, r *http.Request) {
    log.Println("heavy process starts")
    time.Sleep(5 * time.Second)
    log.Println("done")
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte("hello\\n"))
}

func main() {
    http.HandleFunc("/hello", hello)
    http.ListenAndServe(":8000", nil)
}

正常系

これをcurlで叩くと、ずっとサーバが動いていれば

$ ./main
2018/06/19 11:32:57 heavy process starts
2018/06/19 11:33:02 done

のように処理が完了し、

$ curl localhost:8000/hello
hello

クライアントにはこのようにレスポンスが返ります。

異常系

しかしサーバ側はデプロイなどで停止することも多々あります。Ctrl-CSIGINTを投げると

$ ./main
2018/06/19 11:32:43 heavy process starts
^C

このように途中で処理が中断され

$ curl localhost:8000/hello
curl: (52) Empty reply from server