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