gpt4 book ai didi

http.Server ListenAndServer 然后即时关机不起作用

转载 作者:IT王子 更新时间:2023-10-29 01:41:24 25 4
gpt4 key购买 nike

我试图在一个更大的程序中找出一个问题,并编写了这个小测试程序来帮助解决它。

如果我启动一个 http 服务器,然后立即尝试将其关闭,它不会关闭并继续为请求提供服务。我可以对这种行为进行推理,但无法找到解决方法。我假设这是因为服务器在我尝试将其关闭之前尚未完全启动,因此关闭失败并继续启动,然后完成离开它以正常处理请求。

在调用关闭之前,如何确保服务器处于可以关闭的状态?如果您注释掉启动和停止服务器之间的 sleep 功能,您将看到它按预期工作。

package main

import (
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"os/signal"
"time"
)

func main() {
// stop on ^c
quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)

// router
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Println("serving request")
io.WriteString(w, "Hello, world!\n")
})

// start server
srv := &http.Server{Addr: ":8080", Handler: mux}
go func() {
if err := srv.ListenAndServe(); err != nil {
log.Printf("listenAndServe failed: %v", err)
}
}()
fmt.Println("server started")

// time.Sleep(1 * time.Second)

// gracefully stop server
d := time.Now().Add(60 * time.Second)
ctx, cancel := context.WithDeadline(context.Background(), d)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
fmt.Println(err)
}
fmt.Println("server stopped")

<-quit
}

只需运行此程序并访问 http://localhost:8080 .您会看到它会继续为请求提供服务,即使我们试图将其关闭也是如此。

程序的输出应该是:

:; go run main.go
server started
server stopped
2017/07/22 16:17:11 serve failed: http: Server closed

相反,它是:

:; go run main.go
server started
server stopped
serving request
serving request
serving request

最佳答案

您调用 srv.ListenAndServe可以,而且显然是在 srv.Shutdown 之后调用.您可以通过在调用 srv.ListenAndServe 之前向 goroutine 添加日志记录语句来验证这一点.查看在 ListenAndServe 之后调用时关闭是否有效, 你可以取消注释你的 time.Sleep(1 * time.Second) .这里是 Shutdown 的典型用法会在你的 <-quit 之后立即调用它:

func main() {
// stop on ^c
quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)

// router
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Println("serving request")
io.WriteString(w, "Hello, world!\n")
})

// start server
srv := &http.Server{Addr: ":8080", Handler: mux}
go func() {
log.Println("server starting")
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("listenAndServe failed: %v", err)
}
}()
fmt.Println("server started")

<-quit
// gracefully stop server
ctx, cancel := context.WithTimeout(context.Background(), 60 * time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal(err)
}
log.Println("server stopped")
}

关于http.Server ListenAndServer 然后即时关机不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45256166/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com