Как настроить таймауты и корректную остановку HTTP-сервера в Go?
- Почему нельзя использовать http.ListenAndServe без настроек?
- Как сделать graceful shutdown в Go?
http.ListenAndServe по умолчанию без таймаутов: медленные клиенты держат соединения и горутины бесконечно. Нужен свой http.Server с ReadHeaderTimeout, ReadTimeout, WriteTimeout, IdleTimeout. Исходящий http.Client тоже без таймаута по умолчанию — задавать Timeout или контекст с дедлайном. Graceful shutdown: поймать SIGTERM (signal.NotifyContext), вызвать srv.Shutdown(ctx) — сервер перестаёт принимать новые соединения и ждёт текущие запросы до дедлайна.
- WriteTimeout мешает долгим потоковым ответам — для них настраивают отдельно (http.ResponseController)
- Таймаут на обработчик — http.TimeoutHandler или контекст
- Закрывать resp.Body у клиента, иначе соединения не переиспользуются
А ещё Kubernetes ждёт 30 с после SIGTERM — Shutdown должен уложиться
Подробно
Пример:
srv := &http.Server{
Addr: ":8080", Handler: mux,
ReadHeaderTimeout: 5 * time.Second,
ReadTimeout: 10 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 60 * time.Second,
}
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, os.Interrupt)
defer stop()
go func() { _ = srv.ListenAndServe() }()
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
_ = srv.Shutdown(shutdownCtx)
Клиент: client := &http.Client{Timeout: 5 * time.Second}.
Что хотят услышать
- Отсутствие таймаутов по умолчанию.
- Таймауты http.Server и http.Client.
- Shutdown по SIGTERM.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗У http.ListenAndServe и http.Client по умолчанию разумные таймауты, менять их не нужно
- ✗Graceful shutdown в Go — это os.Exit(0) при сигнале
- ✗resp.Body у клиента закрывать не нужно
- ✓Таймауты в http.Server и Client, по SIGTERM — srv.Shutdown(ctx)
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.