Почему веб-сервис 1С прерывается без ошибок при вызове внешних служб и использовании Выполнить()?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с веб-сервисами в 1С:Предприятии 8.3 мы можем столкнуться с неожиданной и сложной для диагностики проблемой: входящий запрос к нашему веб-сервису прерывается без каких-либо ошибок, предупреждений или исключений в журнале регистрации. Такая ситуация часто возникает, когда наш веб-сервис, в свою очередь, выполняет исходящий запрос к другому внешнему сервису, например, к веб-сервису ФНС для проверки данных контрагента. Особенно часто это проявляется при использовании специфической конструкции Выполнить(<Код в режиме предприятия>). Давайте разберем, почему это происходит и как мы можем диагностировать и устранить эту проблему.

Анализируем проблему: особенности прерывания веб-сервисов в 1С

Представим типовую ситуацию: наш веб-сервис 1С принимает запрос на создание контрагента. Перед сохранением данных мы выполняем ряд проверок, одна из которых — запрос к внешнему веб-сервису ФНС для верификации ИНН и КПП. Именно в момент выполнения исходящего запроса к ФНС, наш входящий запрос к веб-сервису 1С внезапно прекращается. Никаких записей в журнал регистрации, никаких сообщений об ошибках в отладчике. Выполнение просто прерывается.

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

Важный нюанс в нашем случае – это использование конструкции Выполнить(<Код в режиме предприятия>) для выполнения проверок. Эта функция позволяет выполнять код, хранящийся в строковой переменной, что может быть удобно для динамического формирования логики, но в то же время значительно снижает предсказуемость и управляемость выполнения кода, особенно при работе с внешними взаимодействиями и в контексте веб-сервисов.

Причины прерывания веб-сервиса без ошибок: разбираем потенциальные источники

Мы выясним, какие факторы могут приводить к такому поведению и как мы можем их идентифицировать.

  1. Таймауты при работе с внешними ресурсами. Это одна из наиболее распространенных причин "молчаливых" прерываний. Когда наш веб-сервис обращается к ФНС, мы устанавливаем соединение и ждем ответа. Если внешний сервис ФНС не отвечает в течение определенного времени, соединение может быть разорвано по таймауту. При этом, если таймаут не обработан явно в коде 1С, это может выглядеть как внезапное прерывание.

    • Явное задание таймаутов: Для объектов WSОпределение, WSПрокси, HTTPСоединение мы должны всегда явно задавать таймаут. Таймаут в 0 секунд считается ошибкой. Рекомендуем устанавливать достаточное время, чтобы покрыть все этапы сетевого взаимодействия (DNS Lookup, Connect, Send, Wait, Receive, Cache Read).
    • Пример установки таймаута для WSПрокси:
      
      WSОпределение = Новый WSОпределение("https://service.fns.ru/somepath?wsdl");
      WSПрокси = Новый WSПрокси(WSОпределение, "http://tempuri.org/", "MyFNSWebService", "MyFNSWebPort");
      WSПрокси.Таймаут = 60; // Устанавливаем таймаут 60 секунд
      // Далее выполняем операции с WSПрокси
      
    • Пример установки таймаута для HTTPСоединение:
      
      //               Сервер,    Порт, Пользователь, Пароль, Прокси, Таймаут
      Соединение = Новый HTTPСоединение("service.fns.ru", , , , , 60); // Таймаут 60 секунд
      Запрос = Новый HTTPЗапрос("/api/check");
      Ответ = Соединение.Получить(Запрос);
      
    • Асинхронные операции: Для длительных операций с внешними сервисами мы можем рассмотреть использование асинхронного режима выполнения, запуская фоновые задания. Это позволит избежать блокировки основного потока выполнения веб-сервиса и не даст клиентскому запросу "зависнуть" в ожидании.
  2. Проблемы с настройками веб-сервера (IIS или Apache). Некорректные настройки веб-сервера, на котором опубликована база 1С, могут вызывать сбои. Мы проверяем:

    • Пулы приложений в IIS: Убедимся, что "Версия среды .NET Framework" установлена в "Без управляемого кода". "Режим управляемого конвейера" может потребовать переключения между "Классический" и "Встроенный" для устранения конфликтов.
    • Брандмауэры и прокси: Удостоверимся, что брандмауэр или прокси-сервер не блокируют исходящие запросы сервера 1С к веб-сервису ФНС.
  3. Блокировки в информационной базе 1С. Даже если мы не видим явных исключений в отладчике, длительная блокировка данных в самой базе 1С, вызванная другими операциями, может привести к "зависанию" или прерыванию работы веб-сервиса. Веб-сервер держит соединение с базой, и если возникают конфликты блокировок или таймауты при ожидании блокировок, это может проявиться как сбой.

  4. Недостаток ресурсов сервера. Нехватка оперативной памяти или ресурсов ЦП на сервере, где развернут веб-сервис или сервер 1С, может привести к аварийному завершению процессов без явных ошибок в журнале регистрации 1С. Это скорее будет видно в системных логах сервера (Event Viewer в Windows, dmesg/syslog в Linux).

  5. Проблемы с безопасностью и правами доступа. Убедимся, что пользователь, под которым запускается процесс rphost (рабочий процесс сервера 1С), имеет необходимые права доступа к внешним сетевым ресурсам и к файловой системе для записи временных файлов, если это требуется. Иногда ошибки доступа могут быть неявно интерпретированы как сбой.

  6. Ошибки в коде веб-сервиса или конфигурации, особенно при использовании Выполнить(). Как мы уже упоминали, использование Выполнить(<Код в режиме предприятия>) может быть ключевой причиной нестабильности. Эта конструкция может приводить к непредсказуемым ситуациям, которые сложно отловить стандартными механизмами обработки исключений. Мы настоятельно рекомендуем переработать код, использующий Выполнить(), на стандартные вызовы процедур и функций, чтобы повысить стабильность и предсказуемость работы веб-сервиса. Это наиболее прямой способ выявить скрытую ошибку, которая может проявляться только в этом специфическом контексте.

Рекомендации по диагностике и устранению проблемы: действенные шаги

Давайте систематизируем шаги, которые помогут нам найти и устранить корень проблемы.

  1. Тщательное логирование и обработка исключений. Мы должны убедиться, что все блоки Попытка...Исключение в нашем коде, особенно те, что связаны с вызовами внешних сервисов, содержат полную обработку ошибок.

    • В блоке Исключение мы всегда используем функцию ИнформацияОбОшибке(), чтобы получить максимально детальное описание произошедшего, включая стек вызовов.
    • Мы регистрируем полученную информацию в журнал регистрации 1С с уровнем важности "Ошибка", а также, по возможности, в собственные логи.
    • Пример правильной обработки исключений:
      
      Попытка
          // ... Ваш код вызова внешнего сервиса ФНС ...
          // Например:
          WSОпределение = Новый WSОпределение("https://example.com/fns?wsdl");
          WSПрокси = Новый WSПрокси(WSОпределение, "http://tempuri.org/", "MyService", "MyPort");
          WSПрокси.Таймаут = 60; // Установим таймаут 60 секунд
          Результат = WSПрокси.МояОперация(ПараметрыЗапроса);
      
      Исключение
          ОписаниеОшибки = ИнформацияОбОшибке();
          Сообщить("Произошла ошибка при вызове сервиса ФНС: " + ОписаниеОшибки, СтатусСообщения.Важное);
          ЗаписьЖурналаРегистрации(НСтр("ru = 'Ошибка при вызове внешнего веб-сервиса ФНС'"),
                                  УровеньВажностиЖурналаСобытий.Ошибка,
                                  ,
                                  ,
                                  ОписаниеОшибки);
          // Мы можем также вернуть ошибку или выбросить исключение, чтобы клиентский код знал о сбое
          Возврат Неопределено;
      КонецПопытки;
      
  2. Анализ технологического журнала 1С и логов веб-сервера.

    • Технологический журнал 1С: Это наш основной инструмент для глубокой диагностики. Мы настраиваем его для сбора максимального количества информации, особенно по событиям `EXCP`, `DBMSSQL`, `CALL`, `CONN` и `TDEADLOCK`. Здесь мы можем обнаружить аварийные падения процессов rphost, взаимоблокировки (`deadlock`), а также неявные ошибки, которые не доходят до журнала регистрации.
    • Логи веб-сервера (IIS/Apache): Проверим логи нашего веб-сервера на предмет ошибок, связанных с обработкой запросов к нашему веб-сервису. Это могут быть ошибки 500-й серии, связанные с внутренними проблемами сервера.
  3. Использование REST-клиентов или SoapUI для диагностики. Мы попробуем вызвать наш веб-сервис 1С с помощью внешних инструментов, таких как Postman или SoapUI. Это позволяет изолировать проблему от клиентского кода 1С и получить более четкое представление об ответе сервиса (или его отсутствии).

  4. Временная переработка кода без Выполнить(<Код в режиме предприятия>). Это критически важный шаг. Мы временно перепишем участок кода, который использует Выполнить(), на прямые вызовы процедур и функций. Это позволит нам исключить нестабильность, вносимую динамическим выполнением кода, и, возможно, выявить ошибку, которая до этого была "заглушена" или проявлялась непредсказуемо.

    • Шаг 1: Создадим обычный общий модуль или процедуру в существующем модуле, куда перенесем логику, которая сейчас находится в строке для Выполнить().
    • Шаг 2: Заменим вызов Выполнить() на прямой вызов этой новой процедуры/функции.
    • Шаг 3: Протестируем веб-сервис снова. Если ошибка исчезнет или проявится в другом, более понятном виде, мы точно знаем, что проблема была в Выполнить().
  5. Проверка сетевых настроек. Убедимся, что нет проблем с сетевым доступом к веб-сервису ФНС со стороны сервера 1С. Мы проверим:

    • Пинги и трассировки: Проверим доступность целевого сервера ФНС.
    • Настройки DNS: Убедимся, что сервер 1С корректно разрешает доменное имя ФНС.
    • Брандмауэры и прокси-серверы: Еще раз проверим, не блокируют ли они исходящие соединения.
  6. Перезапуск служб и перепубликация. В некоторых случаях, после обновлений платформы 1С, может потребоваться перезапуск служб веб-сервера и сервера 1С, а также повторная публикация веб-сервисов. Это может помочь, если пути к каким-либо DLL-файлам (например, wsisapi.dll) изменились или возникли конфликты.

Итоги и лучшие практики

Проблема прерывания веб-сервиса без ошибок является серьезным вызовом для разработчика. Наш первоочередной шаг – это обеспечение полного и детального логирования всех возможных ошибок и исключений. Мы активно используем технологический журнал 1С и системные логи, а также инструменты для тестирования API. Ключевым моментом является отказ от использования Выполнить(<Код в режиме предприятия>) в критически важных местах, особенно там, где происходят взаимодействия с внешними системами. Вместо этого мы предпочитаем явные вызовы процедур и функций, что делает наш код более предсказуемым, стабильным и легким для отладки.

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

← На главную