Загрузка…
Загрузка…
Go · junior · сложность 3
Грациозное завершение работы позволяет HTTP-серверу прекратить принимать новые соединения, позволяя существующим соединениям завершить свои текущие запросы в течение определенного времени ожидания. 1. Прослушивание сигналов: Используйте os/signal, чтобы поймать сигналы завершения (SIGINT, SIGTERM). 2. Создайте экземпляр сервера. Используйте http.Server вместо http.ListenAndServe напрямую, так как http.ListenAndServe блокируется и его сложнее корректно завершить. 3. Запустите сервер в горутине: Запустите server.ListenAndServe() в отдельной горутине, чтобы основная горутина могла прослушивать сигналы. 4. Используйте server.Shutdown(): При получении сигнала завершения вызовите server.Shutdown(ctx). Эта функция не позволяет серверу принимать новые соединения, ждет завершения активных соединений и возвращает результат, когда все будет готово или контекст отменен (из-за тайм-аута). 5. Контекст с тайм-аутом. Используйте context.Context с тайм-аутом для server.Shutdown(), чтобы процесс завершения работы не зависал на неопределенный срок, если соединения не закрываются.
srv := &http.Server{Addr: ":8080", Handler: yourRouter}
go func() {
// server.ListenAndServe() will block
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
// Wait for interrupt signal
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")
// Create a context with a timeout for the shutdown
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Gracefully shut down the server
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server forced to shutdown:", err)
}
log.Println("Server exiting")
```
## Разбор
## Итог
Грациозное завершение работы позволяет HTTP-серверу прекратить принимать новые соединения, позволяя существующим соединениям завершить свои текущие запросы в течение определенного времени ожидания.