Gin为啥需要优雅关闭服务器?
以前以为关闭服务器没有用,但是当你写个一下子启动多个服务器的端口,多重启几次,就会出现下面报错
[GIN-debug] [ERROR] listen tcp :8081: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
[GIN-debug] [ERROR] listen tcp :18083: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
报错原因
每个端口就相当于io,底层的socket就是个文件fd,文件的fd一般会有缓存,即使fd.close()也不会刷盘,如果调用关闭服务器接口,就相当于fs.sync()刷盘再去关闭.
关闭服务代码片段
# 片段1
func WaitSignal(srv *Server) {
c := make(chan os.Signal, 7)
signal.Notify(c, syscall.SIGINT, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, syscall.SIGABRT)
var s os.Signal
for {
select {
case s = <-c:
DEBUG.Println("got os signal ", s.String())
DEBUG.Println("开始关闭http dashboard服务...")
srv.HttpServer.Stop()
time.Sleep(time.Millisecond * 100)
exec.Command("sync").Run()
return
default:
time.Sleep(time.Second)
}
}
}
# 片段2
type HttpServer struct {
Srv *Server
Port string
HttpDashboardServer *HttpDashboardServer
HttpApiServer *HttpApiServer
}
func NewHttpServer(dashPort string, apiPort string) *HttpServer {
hs := &HttpServer{
HttpDashboardServer:NewHttpDashboardServer(dashPort),
HttpApiServer:NewHttpApiServer(apiPort),
}
go hs.Start()
return hs
}
func (hs *HttpServer)Start() {
// 先让Broker装弹
time.Sleep(time.Second * 3)
// 操作api
go hs.HttpApiServer.Serve()
// 面板的api
go hs.HttpDashboardServer.Serve()
}
func (hs *HttpServer) Stop() {
hs.HttpApiServer.ShoutDown()
hs.HttpDashboardServer.ShoutDown()
}