К чему приводит незакрытый resp.Body после HTTP-запроса в Go?

Работа с HTTP в Go resp.Body представляет собой поток тела ответа Необходимо обязательно вызвать defer resp.Body.Close() В противном случае возникает утечка ресурсов, включая TCP-соединения TCP-соединения не…

Короткий ответ

Что ответить на собеседовании

Работа с HTTP в Go resp.Body представляет собой поток тела ответа Необходимо обязательно вызвать defer resp.Body.Close() В противном случае возникает утечка ресурсов, включая TCP-соединения TCP-соединения не освобождаются и остаются занятыми в пуле Результат — исчерпание дескрипторов, замедление работы и падение приложения Закрытие возвращает соединение в пул, чтобы его можно было использовать повторно

Подробный разбор

Ответ с пояснениями

К чему приводит незакрытый resp.Body после HTTP-запроса в Go?

  • Работа с HTTP в Go
  • resp.Body представляет собой поток тела ответа
  • Необходимо обязательно вызвать defer resp.Body.Close()
  • В противном случае возникает утечка ресурсов, включая TCP-соединения
  • TCP-соединения не освобождаются и остаются занятыми в пуле
  • Результат — исчерпание дескрипторов, замедление работы и падение приложения
  • Закрытие возвращает соединение в пул, чтобы его можно было использовать повторно

Итог: если не вызвать Close(), это приведёт к утечкам ресурсов и ухудшению производительности HTTP-клиента.

Подробный ответ

Основной ответ

Если после HTTP-запроса в Go не закрыть resp.Body, соединение с сервером не будет корректно освобождено. Это вызовет утечку ресурсов: TCP-соединения останутся заблокированными, а доступные файловые дескрипторы могут закончиться. Поэтому следующие запросы либо заметно замедлятся, либо полностью зависнут, поскольку в пуле не останется свободных соединений.

Ключевые моменты

  • Ресурс TCP-соединения: HTTP-клиент Go по умолчанию применяет пул соединений (connection pooling). Чтобы соединение можно было использовать снова и вернуть в пул, тело ответа требуется полностью прочитать и закрыть.
  • Memory Leak и FD Leak: открытый resp.Body удерживает память и файловые дескрипторы, снижая производительность и стабильность приложения. Число открытых дескрипторов ограничено операционной системой, поэтому превышение лимита приводит к ошибкам «too many open files».
  • Правильный паттерн: после проверки ошибки выполнения запроса всегда следует сразу вызвать defer resp.Body.Close(), даже если полностью читать тело ответа не требуется. При необходимости его можно прочитать порциями или с помощью io.Copy, а затем закрыть.

Практический контекст

В высоконагруженных сервисах, например при использовании Go 1.18+ с http.Client, некорректно закрытые тела ответов способны сделать сервис недоступным при длительной работе. Для стабильной работы и снижения latency (~50ms) важно правильно обрабатывать resp.Body. Использование defer resp.Body.Close() считается стандартным индустриальным подходом.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку