К статье
Практический материал

Разработка и Конфигурация · 12 мин

1С: как закрыть HTTP соединение и освободить ресурсы

Как правильно закрыть HTTPСоединение в 1С, освободить ресурсы, избежать утечек соединений и ошибок при обмене с веб-сервисами. Примеры кода и FAQ.

Объект HTTPСоединение во встроенном языке 1С используется для обмена данными с веб-сервисами, REST API, сайтами и внешними системами. Каждое такое соединение занимает сетевые ресурсы на клиенте и на сервере, и если им не управлять осознанно, со временем возникают зависания сеансов, ошибки «слишком много соединений» и утечки памяти в рабочих процессах сервера 1С.

Важный нюанс: у объекта HTTPСоединение нет явного метода Закрыть() или Close(). Это часто вызывает вопрос у разработчиков, привыкших к другим языкам. Освобождение ресурсов в 1С выполняется иначе — через разрыв ссылки на объект, работу сборщика мусора и корректную организацию кода обмена.

Ниже разобраны рабочие способы завершения HTTP-соединения, типичные сценарии обмена, ошибки, которые приводят к «зависшим» соединениям, и способы проверить, что ресурсы действительно освобождены.

Как устроено HTTP-соединение в 1С и почему нет метода Закрыть

Объект HTTPСоединение создается конструктором Новый HTTPСоединение(Сервер, Порт, ...) и представляет собой программную обертку над сетевым подключением. Фактическое TCP-соединение платформа устанавливает в момент первого вызова методов Получить, ОтправитьДляОбработки, Записать и других операций обмена.

Управление временем жизни объекта в 1С выполняет механизм подсчета ссылок и сборщик мусора. Пока на объект ссылается хотя бы одна переменная, он существует. Как только последняя ссылка исчезает — переменная выходит из области видимости или ей присваивается другое значение — объект становится кандидатом на удаление, и платформа освобождает связанные сетевые ресурсы.

Из этого следует главный практический вывод: «закрыть» HTTP-соединение в 1С означает разорвать ссылку на объект, а не вызвать специальный метод. Попытки найти в синтакс-помощнике метод Закрыть() у HTTPСоединение бесполезны — его там нет.

Базовый способ: присвоить переменной значение Неопределено

Самый прямой способ освободить соединение — после завершения обмена присвоить переменной, в которой хранится объект, значение Неопределено. После этого ссылка на объект теряется, и платформа может уничтожить его вместе с сетевым подключением.

bsl
HTTPСоединение = Новый HTTPСоединение("api.example.ru", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/v1/data");
Ответ = HTTPСоединение.Получить(Запрос);

// освобождаем соединение
HTTPСоединение = Неопределено;

Обратите внимание: сборщик мусора не обязан уничтожить объект мгновенно после присваивания. На практике освобождение происходит быстро, но гарантировать точный момент нельзя. Для прикладного кода это не имеет значения — важно, что ресурс перестает удерживаться логикой программы.

Если переменная объявлена локально внутри процедуры или функции, присваивать Неопределено явно не обязательно: при выходе из процедуры локальные переменные уничтожаются, и ссылка пропадает сама. Явное обнуление имеет смысл, когда объект хранится в переменной модуля, в реквизите формы или в длительном цикле обмена.

Надежный шаблон обмена с Попытка...Исключение

Главная причина «утечек» соединений — прерывание кода по ошибке до того места, где объект освобождается. Если исключение возникает в середине обмена, строка HTTPСоединение = Неопределено просто не выполняется. Правильный шаблон использует конструкцию Попытка...Исключение...КонецПопытки.

bsl
Функция ПолучитьДанныеСервиса(АдресСервера)
	HTTPСоединение = Неопределено;
	Попытка
		HTTPСоединение = Новый HTTPСоединение(АдресСервера, 443,,,, 30,
			Новый ЗащищенноеСоединениеOpenSSL);
		Запрос = Новый HTTPЗапрос("/api/status");
		Ответ = HTTPСоединение.Получить(Запрос);
		Если Ответ.КодСостояния = 200 Тогда
			Возврат Ответ.ПолучитьТелоКакСтроку();
		Иначе
			ВызватьИсключение "Код ответа: " + Ответ.КодСостояния;
		КонецЕсли;
	Исключение
		HTTPСоединение = Неопределено;
		ВызватьИсключение ОписаниеОшибки();
	КонецПопытки;
	HTTPСоединение = Неопределено;
КонецФункции

Ключевые элементы шаблона: переменная инициализируется до блока Попытка, обнуление выполняется и в ветке ошибки, и после успешного завершения, а таймаут задается явно (в примере — 30 секунд). Без таймаута зависший сервер может удерживать соединение и сеанс 1С неоправданно долго.

Не глушите исключение пустым блоком Исключение КонецПопытки; — так вы потеряете информацию о причине сбоя и усложните диагностику. Минимум — записать ошибку в журнал регистрации через ЗаписьЖурналаРегистрации.

Порядок безопасного обмена
  1. 1
    Создайте HTTPСоединение с явным таймаутом внутри блока Попытка
  2. 2
    Выполните запрос и проверьте код состояния ответа
  3. 3
    В ветке Исключение обнулите переменную и зафиксируйте ошибку в журнале регистрации
  4. 4
    После успешного завершения присвойте переменной Неопределено
  5. 5
    Убедитесь, что объект не сохраняется в глобальных переменных или реквизитах формы без необходимости

Создавать новое соединение или переиспользовать существующее

Частый вопрос — что лучше: держать одно соединение на весь сеанс работы или создавать новое для каждого обмена. Однозначного ответа нет, выбор зависит от сценария.

Сравнение подходов

Новое соединение на каждый обмен

Проще и надежнее: объект умирает вместе с процедурой, нет риска удерживать зависшее соединение. Подходит для редких вызовов и регламентных заданий.

Переиспользование одного соединения

Экономит время на установке TCP и TLS-рукопожатия при частых запросах к одному серверу. Требует дисциплины: хранить объект в переменной модуля и обнулять при завершении работы.

Пул соединений в длительном цикле

При массовой отправке (тысячи запросов) пересоздавайте соединение порциями, например каждые несколько сотен запросов, чтобы сбрасывать накопленное состояние.

Для типовых задач — обмен с банком, отправка чеков, вызов REST API контрагента — рекомендуется создавать соединение локально внутри функции обмена. Это самый предсказуемый вариант: соединение гарантированно освобождается при выходе из функции, даже если разработчик забыл про обнуление.

Переиспользование оправдано при интенсивном обмене с одним сервером, когда накладные расходы на установку защищенного соединения заметны. В этом случае храните объект в переменной модуля и обязательно обнуляйте его при завершении сеанса обмена и при любой ошибке — после сбоя соединение может оказаться в неконсистентном состоянии.

Типичные проблемы и как их диагностировать

Если соединения не освобождаются, симптомы проявляются постепенно: растет потребление памяти рабочими процессами rphost, увеличивается число открытых сетевых подключений, регламентные задания обмена начинают завершаться с ошибками или зависать.

Рост памяти rphostВозможное удержание объектов

Проверьте, не хранятся ли HTTPСоединение в переменных модулей или в фоновых заданиях без обнуления

Ошибки таймаута при обменеСоединения удерживаются дольше нужного

Убедитесь, что таймаут задан явно, а не используется значение по умолчанию

Зависшие фоновые заданияОбмен прерван по ошибке без обработки

Проверьте наличие Попытка...Исключение и обнуления объекта в ветке ошибки

Сбои только под нагрузкойИсчерпание сокетов на сервере

Сократите время жизни соединений, пересоздавайте объект порциями в циклах

Для диагностики полезно зафиксировать в журнале регистрации начало и конец каждого обмена с указанием длительности. Если между «началом» и «концом» систематически появляются записи без пары — код прерывается по исключению, и именно там теряется освобождение объекта.

На уровне операционной системы количество открытых подключений к конкретному серверу можно посмотреть стандартными средствами (например, netstat). Резкий рост числа соединений в состоянии ожидания — косвенный признак того, что объекты создаются чаще, чем освобождаются.

Типичные ошибки
01
Хранение HTTPСоединение в реквизите управляемой формы — объект сериализуется некорректно и ведет себя непредсказуемо между вызовами
02
Пустой блок Исключение — ошибка обмена теряется, а соединение остается висеть до конца сеанса
03
Отсутствие таймаута — зависший внешний сервис блокирует сеанс 1С на неопределенное время
04
Создание соединения внутри цикла по каждой строке данных без необходимости — лишняя нагрузка и риск исчерпать сокеты
05
Поиск несуществующего метода Закрыть() вместо обнуления переменной

Особые сценарии: фоновые задания и длительные обмены

Обмен в фоновых и регламентных заданиях

В регламентных заданиях соединение живет до конца выполнения обработчика. Если задание зависло из-за отсутствия таймаута, соединение и сеанс удерживаются до принудительного завершения. Всегда задавайте таймаут и ограничивайте общую длительность обмена, а при проектировании закладывайте повторную попытку вместо бесконечного ожидания.

Загрузка и отправка больших файлов

Методы Получить и ОтправитьДляОбработки с записью в файл удерживают соединение все время передачи. Для больших файлов увеличьте таймаут пропорционально объему и убедитесь, что после завершения переменная обнуляется, а временные файлы удаляются — иначе к «зависшим» соединениям добавятся забитые каталоги временных файлов.

Прокси и аутентификация

Если обмен идет через прокси (объект ИнтернетПрокси), правила освобождения не меняются: прокси передается в конструктор и умирает вместе с соединением. Отдельно «закрывать» прокси не требуется.

Как проверить, что соединение действительно освобождено

Контрольные точки

Как проверить результат

Журнал регистрации
Норма

Каждому событию начала обмена соответствует событие завершения

Тревожный признак

Есть начатые обмены без завершения — код прерывается по ошибке

Количество сетевых подключений к серверу обмена
Норма

После завершения обмена число соединений возвращается к исходному уровню

Тревожный признак

Соединения накапливаются и не закрываются со временем

Память рабочих процессов
Норма

После серии обменов потребление стабилизируется

Тревожный признак

Память растет монотонно от обмена к обмену

Повторный запуск обмена
Норма

Обмен выполняется стабильно много раз подряд

Тревожный признак

Со временем появляются таймауты или ошибки подключения

Самый надежный тест — прогнать обмен в цикле несколько десятков раз на тестовой базе и наблюдать за памятью процесса и числом подключений. Стабильные показатели означают, что освобождение работает корректно.

Итог

Что важно запомнить

Метода Закрыть у HTTPСоединение нет: объект освобождается при потере ссылки. Создавайте соединение локально внутри функции, задавайте таймаут, оборачивайте обмен в Попытка...Исключение и обнуляйте переменную в обеих ветках. Контролируйте результат по журналу регистрации, памяти процессов и числу открытых подключений.

Частые вопросы

Почему у HTTPСоединение нет метода Закрыть или Close?

Архитектура платформы 1С основана на автоматическом управлении временем жизни объектов через подсчет ссылок. Освобождение ресурса происходит, когда на объект перестают ссылаться переменные. Поэтому вместо явного закрытия используется присваивание значения Неопределено или естественный выход переменной из области видимости.

Что будет, если вообще не освобождать соединение?

Если переменная локальная, объект уничтожится при выходе из процедуры автоматически. Проблемы возникают, когда ссылка хранится в переменной модуля, реквизите формы или общем модуле: тогда соединение живет до конца сеанса, удерживая сетевые ресурсы и память, а при массовом обмене такие объекты накапливаются.

Нужно ли закрывать HTTPЗапрос и HTTPОтвет отдельно?

Нет. Эти объекты также освобождаются сборщиком мусора при потере ссылок. Достаточно не хранить их без необходимости в долгоживущих переменных. Если ответ содержит большое тело, имеет смысл обработать его и обнулить переменную, чтобы быстрее освободить память.

Какой таймаут ставить для соединения?

Универсального значения нет: для быстрых API обычно достаточно десятков секунд, для передачи больших файлов таймаут увеличивают пропорционально объему и скорости канала. Главное правило — таймаут должен быть задан явно, чтобы зависший внешний сервис не блокировал сеанс 1С бесконечно.

Можно ли оборвать зависшее соединение без перезапуска сеанса?

Программно из кода 1С прервать уже выполняющийся синхронный вызов нельзя — он завершится по таймауту или по ответу сервера. Если сеанс завис полностью, его можно завершить через консоль кластера серверов 1С, но делать это следует осознанно: активные транзакции пользователя будут отменены.

Влияет ли защищенное соединение OpenSSL на освобождение ресурсов?

Объект ЗащищенноеСоединениеOpenSSL передается в конструктор и разделяет судьбу HTTPСоединение: отдельно закрывать его не нужно. Однако TLS-рукопожатие — самая затратная часть установки соединения, поэтому при частых запросах к одному серверу переиспользование объекта может быть оправдано.