乐趣区

关于程序员:golang-服务优雅启停

服务优雅启停

服务优雅启停是指服务在敞开之前,做一些善后的工作,比方期待工作完结,开释连贯资源等。

[toc]

实现

上面是一个 http 服务的示例:

type Handler struct {
}

func (h *Handler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {time.Sleep(60 * time.Second)
    fmt.Fprintf(writer, "hello world")
    fmt.Println(time.Now().Unix())
}

func main() {server := http.Server{Addr: ":8080", Handler: &Handler{}}
    go func() {server.ListenAndServe()
    }()
  // 期待 10s 后敞开 server
    time.Sleep(10 * time.Second)
    server.Shutdown(context.Background())
}

10s 后会调用 Shutdown 敞开服务,这个时候发动 http 申请会返回:

在服务敞开之前发动的申请,在 Shutdown 执行之后会期待申请解决实现:

在服务解决申请实现之前,强行敞开服务,客户端会报错,这样就会影响服务运行。

在下面代码的根底上加上优雅启停的逻辑,代码如下:

type Handler struct {
}

func (h *Handler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {time.Sleep(60 * time.Second)
    fmt.Fprintf(writer, "hello world")
    fmt.Println(time.Now().Unix())
}

func main() {server := http.Server{Addr: ":8080", Handler: &Handler{}}
    go func() {server.ListenAndServe()
    }()

    waitExit(func() {fmt.Println("graceful stop")
        server.Shutdown(context.Background())
    })

}

func waitExit(fn func()) {sigl := make(chan os.Signal, 1)
    signal.Notify(sigl, os.Interrupt)
    select {
    case <-sigl:
        fn()}
}

成果:强行敞开服务,会无奈再提供 http 服务,同时期待曾经发动的 connect 执行结束后退出程序。

总结

服务优雅启停目标是对服务正在进行的申请或者执行重要工作期待失常完结,同时进行接管新的申请。

本文由 mdnice 多平台公布

退出移动版