如何结合http.ListenAndServe使用defer?

时间:2017-01-11 15:01:10

标签: http go

在Go中使用http.ListenAndServe()时,会导致阻塞情况,显然只能通过杀死应用程序来停止应用程序。这似乎跳过处理我的defer语句。请参阅下面的代码。当我终止应用程序时,数据库未关闭。如何确保我的defer语句可以运行?

func main() {
  db := NewDB(DBFILENAME)
  defer db.Close()
  http.HandleFunc("/", handler)
  http.ListenAndServe(":80", nil)
}

2 个答案:

答案 0 :(得分:3)

仅当包含它们的函数返回时,

defer语句才会执行。杀死它时,你的主要功能不会返回。所以你需要使用信号和通道。

这是一个解释相同https://www.socketloop.com/tutorials/golang-intercept-ctrl-c-interrupt-or-kill-signal-and-determine-the-signal-type的好链接。

我在上一个项目中遇到了同样的问题。我在项目wshare中实施了类似的解决方案。

在您的情况下,您可以尝试类似

的内容
     ch := make(chan os.Signal, 3)

     signal.Notify(ch, os.Interrupt,syscall.SIGTERM,syscall.SIGINT)


     go func() {
             signalType := <-ch
             signal.Stop(ch)
             log.Println("Exit command received. Exiting...")

             // this is a good place to flush everything to disk
             // before terminating.
             db.Close()
             log.Println("Signal type : ", signalType)

             os.Exit(0)

     }()

答案 1 :(得分:3)

下一个版本1.8中的HTTP包将有一个新的关闭功能,可以正常关闭服务器。 tabs-to-spaces 我认为延迟会起作用。