如何在收到参数后安全关闭 golang 服务 - 最佳实践
How to shut down a golang service safely after receiving parameters - Best practices
我一直在使用 golang 实现服务器。我需要在收到预期参数 'code' 后关闭我的服务器。在关闭服务器之前,我需要重定向到另一个网页。我已经实施如下。此代码正在运行。我需要知道这是否是最好的方法?感谢您的建议..
func main() {
var code string
const port int = 8888
httpPortString := ":" + strconv.Itoa(port)
mux := http.NewServeMux()
fmt.Printf("Http Server initialized on Port %s", httpPortString)
server := http.Server{Addr: httpPortString, Handler: mux}
var timer *time.Timer
mux.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
fmt.Printf("Error parsing the code: %s", err)
}
code = r.Form.Get("code")
if err != nil {
log.Printf("Error occurred while establishing the server: %s", err)
}
http.Redirect(w, r, "https://cloud.google.com/sdk/auth_success", http.StatusMovedPermanently)
timer = time.NewTimer(2 * time.Second)
go func() {
<-timer.C
server.Shutdown(context.Background())
}()
})
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("Error while establishing the service: %s", err)
}
fmt.Println("Finished executing the the service")
}
谢谢..!
从引用的示例中吸取@Peter flushing 的建议和想法here:
f, ok := w.(http.Flusher)
if !ok {
http.Error(w, "no flush support", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "https://cloud.google.com/sdk/auth_success", http.StatusSeeOther)
f.Flush() // <-- ensures client gets all writes
// this is done implicitly on http handler returns, but...
// we're shutting down the server now!
go func() {
server.Shutdown(context.Background())
close(idleConnsClosed)
}()
查看 idleConnsClosed
setup/cleanup 的完整游乐场版本:https://play.golang.org/p/UBmLfyhKT0B
P.S。不要使用 http.StatusMovedPermanently
除非你真的希望用户永远不再使用来源 URL。用户的浏览器将缓存此 (301) 代码 - 而不会访问您的服务器 - 这可能不是您想要的。如果您想要临时重定向,请使用 http.StatusSeeOther
(代码 303)。
我一直在使用 golang 实现服务器。我需要在收到预期参数 'code' 后关闭我的服务器。在关闭服务器之前,我需要重定向到另一个网页。我已经实施如下。此代码正在运行。我需要知道这是否是最好的方法?感谢您的建议..
func main() {
var code string
const port int = 8888
httpPortString := ":" + strconv.Itoa(port)
mux := http.NewServeMux()
fmt.Printf("Http Server initialized on Port %s", httpPortString)
server := http.Server{Addr: httpPortString, Handler: mux}
var timer *time.Timer
mux.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
fmt.Printf("Error parsing the code: %s", err)
}
code = r.Form.Get("code")
if err != nil {
log.Printf("Error occurred while establishing the server: %s", err)
}
http.Redirect(w, r, "https://cloud.google.com/sdk/auth_success", http.StatusMovedPermanently)
timer = time.NewTimer(2 * time.Second)
go func() {
<-timer.C
server.Shutdown(context.Background())
}()
})
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("Error while establishing the service: %s", err)
}
fmt.Println("Finished executing the the service")
}
谢谢..!
从引用的示例中吸取@Peter flushing 的建议和想法here:
f, ok := w.(http.Flusher)
if !ok {
http.Error(w, "no flush support", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "https://cloud.google.com/sdk/auth_success", http.StatusSeeOther)
f.Flush() // <-- ensures client gets all writes
// this is done implicitly on http handler returns, but...
// we're shutting down the server now!
go func() {
server.Shutdown(context.Background())
close(idleConnsClosed)
}()
查看 idleConnsClosed
setup/cleanup 的完整游乐场版本:https://play.golang.org/p/UBmLfyhKT0B
P.S。不要使用 http.StatusMovedPermanently
除非你真的希望用户永远不再使用来源 URL。用户的浏览器将缓存此 (301) 代码 - 而不会访问您的服务器 - 这可能不是您想要的。如果您想要临时重定向,请使用 http.StatusSeeOther
(代码 303)。