При разработке интеграционных решений на базе HTTP-сервисов 1С программисты часто сталкиваются с коварной проблемой: при передаче небольших пакетов данных сервис работает безупречно, но как только объем XML-данных превышает «порог» примерно в 1.2–1.3 Мб (около 1296 Кб), клиентские приложения внезапно перестают получать ответ. Браузер Chrome выдает ошибку «Не удается получить доступ к сайту» (Connection Reset), а утилита Postman рапортует о невозможности получить данные: «Could not get any response».
Самое загадочное в этой ситуации — поведение логов веб-сервера IIS. Если мы проанализируем файл логов IIS, то обнаружим, что веб-сервер регистрирует успешную обработку запроса со статус-кодом 200 OK. Получается парадокс: система 1С отработала без ошибок, IIS считает, что успешно отдал данные, но клиент на другом конце сетевого провода остался ни с чем. Выясним причину этой проблемы и подробно разберем несколько эффективных способов её решения.
Проанализируем физику процесса взаимодействия платформы 1С, веб-сервера IIS и сетевого клиента. Проблема кроется в архитектурных особенностях взаимодействия модуля расширения веб-сервера 1С (wsisapi.dll) и IIS. Когда размер ответа превышает определенный лимит (обычно около 1 Мб), в работу вступают встроенные оптимизаторы и защитные механизмы IIS, которые некорректно обрабатывают динамические потоки данных. Происходит аварийный сброс TCP-соединения (так называемый TCP RST), из-за чего клиент видит сетевую ошибку, хотя сам веб-сервер считает транзакцию завершенной.
Рассмотрим по шагам основные причины возникновения этого сбоя и способы их устранения.
По умолчанию в IIS включена функция динамического сжатия содержимого (Dynamic Content Compression). Веб-сервер пытается сжать генерируемый 1С XML-пакет «на лету» с помощью алгоритма GZIP перед отправкой клиенту.
Когда размер динамического XML-ответа переваливает за отметку 1 Мб, модуль сжатия IIS из-за особенностей работы с wsisapi.dll не может корректно выделить буфер под динамический поток. Происходит внутренний сбой в рабочем процессе IIS (w3wp.exe), приводящий к немедленному закрытию сетевого сокета. При этом заголовок ответа со статусом 200 веб-сервер отправить успевает, что и фиксируется в его логах.
Чтобы отключить динамическое сжатие для вашей публикации 1С, выполним следующие действия:
iisreset в командной строке от имени администратора).Если сжатие трафика для вашей системы критично, рекомендуется осуществлять его силами самой 1С (например, упаковывать XML в ZIP-архив средствами платформы) либо использовать внешние прокси-серверы (например, Nginx), установленные перед IIS, которые гораздо стабильнее справляются со сжатием динамических потоков данных.
При стандартном формировании ответа в 1С разработчики часто используют метод УстановитьТелоИзСтроки(). Посмотрим на типичный пример кода, который может приводить к ошибкам при больших объемах данных:
// Проблемный вариант формирования ответа
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/xml; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(СтрокаXML, КодировкаТекста.UTF8);
Возврат Ответ;
При использовании метода УстановитьТелоИзСтроки() веб-сервер не знает заранее точный размер генерируемого контента в байтах. Поэтому IIS отправляет данные клиенту по частям (чанками), автоматически добавляя заголовок Transfer-Encoding: chunked. Передача больших объемов данных чанками через ISAPI-расширение 1С часто блокируется сетевыми экранами, антивирусами или защитными модулями самого IIS, расценивающими такой поток как потенциальную угрозу безопасности.
Для решения этой проблемы перепишем логику формирования тела ответа в 1С. Мы принудительно преобразуем XML-строку в двоичные данные. В этом случае платформа самостоятельно вычислит точный размер пакета в байтах и передаст его в заголовке Content-Length, полностью исключая использование потоковой передачи (chunked).
Рассмотрим правильный пример реализации кода в 1С:
// Оптимальный вариант формирования ответа
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/xml; charset=utf-8");
// Преобразуем строковый XML в ДвоичныеДанные
ДвоичныеДанныеОтвета = ПолучитьДвоичныеДанныеИзСтроки(СтрокаXML, КодировкаТекста.UTF8, Истина);
// Устанавливаем двоичные данные в тело ответа
Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеОтвета);
Возврат Ответ;
Применение этого несложного приема позволяет веб-серверу IIS передавать данные единым пакетом с четко определенным размером, что кардинально повышает стабильность доставки XML-документов большого объема.
Если публикация вашей информационной базы работает в 32-разрядном пуле приложений IIS (или в настройках пула включена опция поддержки 32-битных приложений), рабочий процесс w3wp.exe сталкивается с жесткими ограничениями операционной системы на выделение непрерывных участков оперативной памяти.
При формировании тяжелых XML-структур в памяти 1С реальный объем потребляемой RAM может в 5–10 раз превышать итоговый размер файла на диске из-за создания сложных объектных моделей (DOM). При достижении размера XML-строки в ~1.2 Мб процесс веб-сервера может столкнуться с фрагментацией адресного пространства памяти и «тихо» оборвать сетевую сессию.
Проанализируем настройки вашего IIS и выполним следующие изменения:
C:\Program Files\1cv8\..., а не в C:\Program Files (x86)\1cv8\....Нередко виновниками обрыва соединения на объемах более 1 Мб выступают системы глубокого анализа пакетов (DPI), брандмауэры или локальное антивирусное ПО, установленное на сервере. Большие объемы XML-структур, передаваемые единым непрерывным потоком, могут распознаваться защитными системами как попытка атаки типа «XML Entity Expansion» или «XML Injection».
Для локализации проблемы выполним следующие диагностические действия:
w3wp.exe в список исключений сканирования вашего антивируса.Стоит также помнить о возможных внутренних ошибках самой платформы 1С. В истории развития технологической платформы 1С:Предприятие 8.3 были зафиксированы релизы (в частности, в ветках 8.3.11–8.3.12), в которых сериализация больших объемов данных в HTTP-сервисах приводила к аварийному завершению сеанса связи. Начиная с версии 8.3.13, данные платформенные баги были успешно устранены разработчиками фирмы «1С».
Если все предыдущие настройки IIS выполнены верно, но ошибка сохраняется, настоятельно рекомендуем обновить технологическую платформу 1С:Предприятие на сервере до актуального стабильного релиза.