Каждый разработчик или системный администратор 1С рано или поздно сталкивается с ситуацией, когда стабильно работавший годами интеграционный веб-сервис начинает вести себя непредсказуемо. Пользователи жалуются на периодические ошибки подключения (код ответа сервера 500), но при попытке оперативно разобраться в проблеме оказывается, что через 10–20 минут всё «само собой» восстанавливается. Если мгновенный отклик не является обязательным, альтернативой проблемным веб-службам может стать автоматизация регулярного обмена данными по расписанию.
В этой статье мы подробно проанализируем причины такого поведения связки платформы 1С и веб-сервера (на примере Microsoft IIS), выясним, почему сервисы «ломаются» и «чинятся» без внешнего вмешательства, и разработаем пошаговый план локализации и решения этой проблемы даже в условиях, когда системные администраторы компании не могут оказать квалифицированную помощь.
Эффект «самоисцеления» (self-healing) веб-сервисов не является случайностью. Он обусловлен штатными механизмами работы веб-сервера IIS и платформы 1С. Рассмотрим подробнее, какие именно процессы за этим стоят:
DefaultAppPool) установлен лимит неактивности в 20 минут. Если за это время к базе данных через веб-сервис никто не обращался, рабочий процесс веб-сервера w3wp.exe принудительно завершает свою работу для высвобождения оперативной памяти сервера. Когда поступает новый запрос, происходит так называемый «холодный старт»: процесс запускается заново, инициализирует библиотеку веб-расширения 1С wsisapi.dll и пытается установить сеанс с базой данных. На высоконагруженном или слабом сервере этот процесс может занять слишком много времени, превышая таймаут ожидания клиента. Клиент получает ошибку 500, но сам процесс инициализации на сервере успешно завершается в фоновом режиме. Следующий запрос, отправленный через пару минут, отрабатывает мгновенно — веб-сервис «ожил».default.vrd обычно задействован механизм пулирования соединений. Если на сервер обрушивается лавинообразный поток запросов или СУБД блокирует транзакции, свободные соединения в пуле быстро заканчиваются. Все последующие клиенты получают ошибку HTTP 500 (Internal Server Error). Спустя некоторое время «зависшие» соединения закрываются по таймауту, пул очищается, и веб-сервис снова начинает стабильно отвечать на запросы.rphost.exe завершает работу, а новые сессии еще не мигрировали на вновь запущенный процесс, веб-сервер IIS теряет связь с кластером 1С. Пользователь видит ошибку 500. Как только новый рабочий процесс запускается и стабилизируется, работоспособность веб-сервиса полностью восстанавливается.Если серверы регулярно «умирают» в течение рабочего дня и требуют перезагрузки, это напрямую связано со сбоями веб-сервисов. Проанализируем наиболее частые системные конфликты:
Max Server Memory), СУБД со временем заберет под свои нужды практически всю доступную ОЗУ. Рабочему процессу IIS w3wp.exe или процессам 1С rphost.exe в моменты пиковых запросов просто не хватает оперативной памяти для обработки сериализации данных веб-сервиса, что мгновенно приводит к аварийному завершению процессов и ошибке 500.Рассмотрим ситуацию: веб-сервис производит чтение данных из базы ЗУП (проверяет проведение документа и его сумму по GUID). Если в этот момент в ЗУП выполняется регламентный расчет заработной платы, закрытие периода или проведение тяжелых кадровых документов, таблицы базы данных могут оказаться временно заблокированы транзакцией СУБД. Запрос веб-сервиса встает в очередь ожидания блокировки. Если время ожидания превышает установленный на веб-сервере таймаут (обычно около 30-60 секунд), соединение разрывается с ошибкой сервера, хотя сам код веб-сервиса написан абсолютно корректно и не менялся годами. Как только тяжелая транзакция завершается и блокировка снимается, веб-сервис снова начинает мгновенно возвращать результат. При регулярных задержках из-за высокой нагрузки на общую базу можно рассмотреть выделение учёта в отдельный контур, используя подбор решений для переноса данных в ЗУП.
Если штатные администраторы не могут оперативно решить проблему, разработчик 1С может самостоятельно локализовать ошибку и оптимизировать работу веб-публикации. Пройдем по шагам весь процесс настройки.
Для предотвращения «засыпания» веб-сервиса и устранения проблемы холодного старта необходимо изменить параметры пула приложений в диспетчере IIS:
DefaultAppPool), нажмите на него правой кнопкой мыши и выберите Дополнительные параметры.Параметры пула соединений 1С описываются в файле публикации default.vrd, который находится в каталоге виртуального каталога IIS (например, C:\inetpub\wwwroot\ИмяВашейПубликации). Откроем этот файл в текстовом редакторе и настроим параметры пула соединений внутри тега point:
<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
base="/zup"
ib="Srvr="SQLServer";Ref="zup_db";">
<ws>
<point name="CheckDoc" alias="checkdoc.1cws" enable="true"/>
</ws>
<pool size="20" maxAge="60" expireTime="120" enable="true"/>
</point>
Разберем параметры тега pool подробнее:
size — задает максимальное количество удерживаемых в пуле соединений с базой. Для часто вызываемых веб-сервисов рекомендуется увеличить это значение (например, до 20–30), чтобы новые запросы не ждали освобождения соединений.maxAge — максимальное время жизни соединения в пуле (в секундах). Установка этого значения в пределах 60–120 секунд позволяет вовремя уничтожать устаревшие и «зависшие» сессии 1С.expireTime — время ожидания завершения активности неиспользуемого соединения перед его удалением.Поскольку стандартный Журнал регистрации часто молчит при падении веб-сервера, нам необходимо принудительно оборачивать все операции веб-сервиса в блоки обработки ошибок и записывать логи самостоятельно. Рассмотрим пример реализации метода веб-сервиса с логированием входящих параметров и ошибок:
Функция ПолучитьДанныеДокумента(ИдентификаторДокумента) Экспорт
ИмяСобытияЖР = "Интеграция.ВебСервис.ПолучитьДанныеДокумента";
Попытка
// Логируем факт вызова веб-сервиса
ЗаписьЖурналаРегистрации(ИмяСобытияЖР,
УровеньЖурналаРегистрации.Информация,
,
,
"Запрос принят. Параметр ИдентификаторДокумента: " + ИдентификаторДокумента);
// Поиск документа по GUID в базе ЗУП
УникальныйИд = Новый УникальныйИдентификатор(ИдентификаторДокумента);
СсылкаНаДокумент = Документы.ПриемНаРаботу.ПолучитьСсылку(УникальныйИд);
Если СсылкаНаДокумент.Пустая() Тогда
ВызватьИсключение "Документ с указанным GUID не найден в базе данных!";
КонецЕсли;
// Формируем результат для возврата
РезультатСтруктура = Новый Структура;
РезультатСтруктура.Вставить("Проведен", СсылкаНаДокумент.Проведен);
РезультатСтруктура.Вставить("Сумма", СсылкаНаДокумент.СуммаДокумента);
// Преобразуем в JSON строку (или XML по спецификации)
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, РезультатСтруктура);
РезультатСтрока = ЗаписьJSON.Закрыть();
// Успешный финал работы
ЗаписьЖурналаРегистрации(ИмяСобытияЖР,
УровеньЖурналаРегистрации.Информация,
,
,
"Запрос успешно обработан. Результат: " + РезультатСтрока);
Возврат РезультатСтрока;
Исключение
// Обязательно перехватываем и подробно записываем ошибку в ЖР
ПодробноеОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(ИмяСобытияЖР,
УровеньЖурналаРегистрации.Ошибка,
,
,
"Произошел сбой при обработке запроса. Ошибка: " + ПодробноеОписаниеОшибки);
// Пробрасываем ошибку дальше вызывающему приложению
ВызватьИсключение "Ошибка на стороне веб-сервиса 1С: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
КонецФункции
Если ошибка происходит на уровне платформы 1С (например, аварийно завершается процесс rphost.exe или библиотека wsisapi.dll вызывает критический сбой памяти), запись в Журнал регистрации физически не сможет создаться. Для расследования таких инцидентов нужно использовать Технологический журнал (ТЖ).
Создадим файл конфигурации ТЖ с именем logcfg.xml и сохраним его в каталоге конфигов платформы на сервере (обычно это C:\Program Files\1cv8\conf\). Настроим его на сбор только критических исключений (событие EXCP), чтобы не создавать избыточную нагрузку на дисковую подсистему сервера:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/8.2/config">
<log location="C:\1C_Logs\EXCP_Logs" history="48">
<event filter="EXCP">
<eq property="Name" value="EXCP"/>
</event>
<property name="all"/>
</log>
</config>
После создания этого файла платформа автоматически начнет собирать информацию обо всех аварийных завершениях и исключительных ситуациях в папку C:\1C_Logs\EXCP_Logs. Анализируя лог-файлы ТЖ, вы сможете точно увидеть контекст выполнения кода 1С в миллисекунду падения процесса, что позволит локализовать причину сбоя (будь то ошибка СУБД, утечка памяти или взаимная блокировка сессий).
Если веб-сервис выдает ошибку 500, а логи 1С пусты, обязательно загляните в системные логи операционной системы: дополнительно для профилактики сбоев полезно настроить автоматическое обновление и тестирование баз 1С во внерабочее время.
rphost.exe или библиотеки wsisapi.dll. Сопоставление времени этих событий с моментами жалоб пользователей позволит вам предоставить «неопровержимые доказательства» системным администраторам, если проблема кроется в нехватке аппаратных ресурсов сервера или багах операционной системы.Таким образом, используя комплексный подход — от детальной настройки веб-сервера IIS и оптимизации файла публикации default.vrd до внедрения Технологического журнала и точечного перехвата ошибок в коде веб-сервиса, мы можем гарантировать стабильную работу интеграционных механизмов 1С и быструю локализацию любых возникающих сбоев.