Метод http.Server.Shutdown
Метод http.Server.Shutdown обеспечивает корректное завершение работы HTTP сервера.
Он позволяет серверу дождаться завершения всех активных запросов, прежде чем остановиться.
В первый параметр метод принимает контекст, который определяет максимальное время ожидания завершения соединений.
Метод возвращает ошибку, если во время завершения работы что-то пошло не так.
Синтаксис
func (srv *Server) Shutdown(ctx context.Context) error
Пример
Давайте создадим HTTP сервер, который корректно завершает работу при получении сигнала прерывания:
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
})
srv := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("Server error: %v\n", err)
}
}()
fmt.Println("Server started on :8080")
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
fmt.Println("Shutting down server...")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
fmt.Printf("Server shutdown error: %v\n", err)
}
fmt.Println("Server gracefully stopped")
}
Результат выполнения кода:
"Server started on :8080"
"Shutting down server..."
"Server gracefully stopped"
Пример
Рассмотрим ситуацию, когда сервер ожидает завершения активных запросов в течение ограниченного времени:
package main
import (
"context"
"fmt"
"net/http"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/slow", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(5 * time.Second)
fmt.Fprintf(w, "Slow response")
})
srv := &http.Server{
Addr: ":8080",
Handler: mux,
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("Server error: %v\n", err)
}
}()
fmt.Println("Server started on :8080")
time.Sleep(2 * time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
fmt.Printf("Shutdown error: %v\n", err)
}
fmt.Println("Server stopped")
}
Результат выполнения кода:
"Server started on :8080"
"Shutdown error: context deadline exceeded"
"Server stopped"
Смотрите также
-
функцию
http.Server.ListenAndServe,
которая запускает HTTP сервер и начинает прослушивание подключений -
функцию
http.Server.Close,
которая немедленно закрывает все активные соединения -
функцию
http.Server.Serve,
которая обслуживает подключения на указанном слушателе -
функцию
http.Server.ListenAndServeTLS,
которая запускает HTTPS сервер с использованием TLS