Go语言教程之边写边学:如何优雅地处理HTTP服务器关闭
在Go中,可以使用http.服务器的Shutdown() 方法。此方法提供了一种正常关闭服务器的方法,允许服务器在关闭所有连接之前完成任何活动请求的处理。
下面是一个示例代码,演示了如何在Go中正常关闭HTTP服务器:
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
// 创建http服务器实例srv := &http.Server{
Addr: ":8080",
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Simulate a long-running request
time.Sleep(10 * time.Second)
w.Write([]byte("Hello, World!"))
}),
}
// 接收信号的通道signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
// go协程中启动服务go func() {
log.Printf("Server listening on %s\n", srv.Addr)
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
// 等待关闭信号sig := <-signalCh
log.Printf("Received signal: %v\n", sig)
// 创建超时上下文ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// 优雅的关闭服务if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("Server shutdown failed: %v\n", err)
}
log.Println("Server shutdown gracefully")
}
在此示例中,我们创建了一个新的HTTP服务器,并在单独的goroutine中启动它。我们还创建了一个接收信号的通道,并等待信号关闭服务器。当收到信号时,我们创建一个超时的上下文,并在服务器上调用Shutdown() 方法。如果服务器在超时后仍在处理请求,它将强制终止所有活动连接。
请注意,如果有任何资源需要在服务器关闭之前清理,则应将它们包含在Shutdown() 函数中。这将确保在服务器终止之前清理它们。
系列文章