什么是优雅关机?
http-server运行过程中,若进程被关闭,那么正在处理的请求可能只被处理了一半就停止了,可能会产生数据的不一致。
优雅关机是指:
- 首先,停止接收新请求;
- 然后,等待队列中的请求被处理完毕;
- 最后,应用程序退出;
net/http原生的shutdown函数支持优雅关机。
优雅关机的实现
首先,在goroutine中启动http-server:
srv := &http.Server{
Addr: ":8090",
Handler: r,
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal("listen: ", err)
} else {
log.Println("ListenAndServe break")
}
}()
然后,在main中监听关机信号:
- SIGTERM: kill的默认信号;
- SIGINT:kill -2,一般是Ctrl+C的退出;
- SIGKILL:kill -9,捕获不到;
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<- quit
net/http优雅关机的实现原理
优雅关机是调用net/http的srv.Shutdown(ctx)实现的,该方法会:
- 先拒绝后面的connection请求;
- 然后再慢慢的处理未处理完毕的请求;
- 当未处理的请求一旦被处理完毕,其connection变成Idle,然后被Close()掉;
func (srv *Server) Shutdown(ctx context.Context) error {
...
for _, f := range srv.onShutdown {
go f()
}
...
ticker := time.NewTicker(shutdownPollInterval)
defer ticker.Stop()
for {
if srv.closeIdleConns() {
return lnerr
}
select {
case <-ctx.Done():
return ctx.Err()
case <-ticker.C:
}
}
}
另外,当调用Shutdown()后,srv.ListenAndServer方法将退出,并返回ErrServerClose错误。
参考链接
优雅地关机或重启
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)