Как найти ошибку в HTTP-сервисе 1С: точки останова, журналы, нагрузка

· 10 мин

Содержание

Чтобы отлаживать HTTP-сервис 1С по шагам, включите в файле публикации default.vrd строку <debug enable="true" protocol="http" url="http://<машина разработчика>:1550"/>, в Конфигураторе разрешите отладку по протоколу HTTP и настройте автоматическое подключение предметов отладки для HTTP-сервисов. После этого точка останова в модуле сервиса срабатывает на каждый внешний запрос из Postman или curl.

Типичная ситуация: интернет-магазин шлёт заказ в 1С, а в ответ получает 500 Internal Server Error без подробностей. Пользователь ничего не видит, ошибка где-то на сервере. Такой сбой ловят по цепочке: воспроизводимый тестовый запрос, точка останова, журнал регистрации, техжурнал. Для проблем со скоростью добавляется стресс-тест.

Что подготовить перед отладкой HTTP-сервиса

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

📦 Минимальный набор:

  • Тестовая копия базы — файловая или клиент-серверная, с той же конфигурацией.
  • Веб-сервер — IIS или Apache на той же машине или в одной сети, с установленным модулем расширения веб-сервера из дистрибутива платформы.
  • Публикация базы — через Администрирование → Публикация на веб-сервере в Конфигураторе, запущенном от имени администратора. Отметьте флаг публикации HTTP-сервисов.
  • Клиент для запросов — Postman, Insomnia или curl из командной строки.
  • Пользователь 1С для сервиса — отдельный, с ролью только на нужные данные. Под ним внешняя система будет авторизоваться.

Проверьте адрес сервиса. Он собирается так:

http://<сервер>/<имя публикации>/hs/<Корневой URL сервиса>/<шаблон URL>

Например, http://localhost/trade/hs/api/orders/123. Если на этом шаге браузер возвращает 404 — дальше отлаживать бессмысленно, сначала чините публикацию (см. раздел про коды ошибок).

Как включить отладку HTTP-сервисов в Конфигураторе

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

Шаг 1. Протокол отладки HTTP

В Конфигураторе откройте Сервис → Параметры → Отладка и выберите отладку по протоколу HTTP. Конфигуратор запустит локальный сервер отладки — по умолчанию на порту 1550.

Для клиент-серверной базы отладку должен разрешить и сервер 1С: служба агента запускается с ключами -debug -http. Перезапуск службы сервера 1С обрывает сеансы всех пользователей — меняйте параметры службы на тестовом сервере или в согласованное окно.

Шаг 2. Правка default.vrd

Откройте файл default.vrd в каталоге публикации (для IIS обычно C:\inetpub\wwwroot\<имя публикации>). Добавьте внутрь элемента point строку debug:

<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="/trade"
       ib="Srvr=&quot;srv1c&quot;;Ref=&quot;trade&quot;;">
  <debug enable="true" protocol="http" url="http://dev-pc:1550"/>
  <httpServices publishByDefault="true"/>
</point>

В url укажите машину, где запущен Конфигуратор, а не сервер 1С. Порт 1550 откройте в брандмауэре этой машины.

После правки default.vrd перезапустите пул приложений IIS или службу Apache — иначе модуль расширения продолжит работать со старыми настройками.

Шаг 3. Автоматическое подключение

В Конфигураторе выберите Отладка → Подключение, нажмите кнопку автоматического подключения и отметьте предметы отладки для HTTP-сервисов. Теперь каждый сеанс, который веб-сервер откроет под сервис, сам появится в отладчике.

Поставьте точку останова (F9) в функции-обработчике метода, например ЗаказыPOST(Запрос), и отправьте запрос. Выполнение остановится, и вы увидите содержимое объекта Запрос.

Что смотреть в отладчике

ВыражениеЧто показывает
Запрос.HTTPМетодGET, POST, PUT, DELETE
Запрос.ПараметрыURLПараметры из шаблона: {Номер} из /orders/{Номер}
Запрос.ПараметрыЗапросаВсё, что после ? в адресе
Запрос.ЗаголовкиContent-Type, Authorization и прочее
Запрос.ПолучитьТелоКакСтроку("UTF-8")Тело запроса — JSON или XML

Пока вы стоите на точке останова, клиент ждёт ответа. В Postman увеличьте таймаут в настройках, иначе он оборвёт соединение раньше, чем вы дойдёте до ошибки.

Тестовые запросы: Postman, curl и HTTPСоединение

Отладка начинается с воспроизводимого запроса. Один раз соберите его — и гоняйте после каждой правки.

curl

GET-запрос с базовой авторизацией:

curl -i -u ApiUser:Pass123 "http://localhost/trade/hs/api/orders/123"

POST с телом из файла:

curl -i -u ApiUser:Pass123 -H "Content-Type: application/json; charset=utf-8" --data-binary @order.json "http://localhost/trade/hs/api/orders"

Ключ -i выводит заголовки ответа — по ним видно код состояния и кодировку. --data-binary передаёт файл без изменений, в отличие от -d, который убирает переводы строк.

Postman

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

Из самой 1С

Проверить сервис можно обработкой с кодом на сервере:

Соединение = Новый HTTPСоединение("localhost", 80, "ApiUser", "Pass123", , 60);
Запрос = Новый HTTPЗапрос("/trade/hs/api/orders/123");
Ответ = Соединение.Получить(Запрос);
Сообщить(Строка(Ответ.КодСостояния) + ": " + Ответ.ПолучитьТелоКакСтроку("UTF-8"));

Последний параметр конструктора — таймаут в секундах. Для HTTPS добавьте седьмым параметром Новый ЗащищенноеСоединениеOpenSSL() и порт 443.

Журнал регистрации и обработка исключений

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

Шаблон обработчика с перехватом ошибки

Без Попытка…Исключение необработанная ошибка уходит клиенту как код 500 с текстом ошибки платформы. Клиенту это бесполезно, а иногда и опасно: в тексте видны имена модулей и строки кода.

Функция ЗаказыGET(Запрос)

	ИдЗапроса = Строка(Новый УникальныйИдентификатор);

	Попытка
		Номер = Запрос.ПараметрыURL.Получить("Номер");
		Если Номер = Неопределено Тогда
			Возврат ОтветJSON(400, "Не передан номер заказа", ИдЗапроса);
		КонецЕсли;

		Данные = НайтиЗаказ(Номер); // ваша функция поиска
		Если Данные = Неопределено Тогда
			Возврат ОтветJSON(404, "Заказ не найден", ИдЗапроса);
		КонецЕсли;

		Возврат ОтветJSON(200, Данные, ИдЗапроса);

	Исключение
		ЗаписьЖурналаРегистрации("API.Заказы.GET",
			УровеньЖурналаРегистрации.Ошибка,
			Метаданные.HTTPСервисы.API, ,
			"Запрос " + ИдЗапроса + Символы.ПС
				+ ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		Возврат ОтветJSON(500, "Внутренняя ошибка сервиса", ИдЗапроса);
	КонецПопытки;

КонецФункции

Функция ОтветJSON(КодСостояния, Содержимое, ИдЗапроса)

	Ответ = Новый HTTPСервисОтвет(КодСостояния);
	Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
	Ответ.Заголовки.Вставить("X-Request-ID", ИдЗапроса);

	Если ТипЗнч(Содержимое) = Тип("Строка") Тогда
		Содержимое = Новый Структура("message", Содержимое);
	КонецЕсли;

	Запись = Новый ЗаписьJSON;
	Запись.УстановитьСтроку();
	ЗаписатьJSON(Запись, Содержимое);

	Ответ.УстановитьТелоИзСтроки(Запись.Закрыть(), КодировкаТекста.UTF8,
		ИспользованиеByteOrderMark.НеИспользовать);
	Возврат Ответ;

КонецФункции

Приём с X-Request-ID экономит время на разборе: интегратор присылает идентификатор из заголовка ответа, вы находите его в журнале регистрации отбором по комментарию.

ИспользованиеByteOrderMark.НеИспользовать убирает метку BOM в начале ответа. Многие JSON-парсеры на PHP и JavaScript спотыкаются о неё с ошибкой разбора на первом символе.

Как читать журнал

Откройте журнал регистрации и поставьте отбор:

  • 🔎 по событию — API.Заказы.GET, имя из кода;
  • 👤 по пользователю — учётная запись, под которой ходит внешняя система;
  • ⏱ по интервалу — минута, когда интегратор получил ошибку.

Логируйте ошибки всегда, а успешные запросы — только на время разбора. Запись каждого вызова с телом раздувает журнал за неделю до гигабайт.

Технологический журнал и замер производительности

Журнал регистрации пишет только то, что вы сами туда отправили. Если ошибка возникает до вашего кода — при авторизации, при разборе URL, на уровне платформы — нужен технологический журнал.

Минимальный logcfg.xml

Файл кладут в каталог conf установленной платформы (например, C:\Program Files\1cv8\conf) на машине, где выполняется код сервиса: на сервере 1С для клиент-серверной базы, на веб-сервере — для файловой.

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="C:\TechLog\http" history="24">
    <event>
      <eq property="name" value="EXCP"/>
    </event>
    <event>
      <eq property="name" value="CALL"/>
    </event>
    <property name="all"/>
  </log>
</config>

history="24" — хранить 24 часа. События EXCP показывают исключения, CALL — серверные вызовы с длительностью. Каталог журнала нужно создать заранее и дать на него права записи учётной записи, под которой работает служба.

Техжурнал без отборов быстро забивает диск — включайте его на время разбора и удаляйте logcfg.xml, когда закончили.

Замер производительности

Когда HTTP-сервис подключён к отладчику, включите Отладка → Замер производительности и отправьте запрос. Конфигуратор покажет, какие строки модуля заняли больше всего времени. Чаще всего это:

  • 🐢 запрос к базе внутри цикла по строкам заказа;
  • 🐢 обращение к реквизитам через точку (Заказ.Контрагент.ИНН) в цикле;
  • 🐢 запись объекта с полным перепроведением там, где хватило бы записи регистра.

Нагрузочное тестирование и повторное использование сеансов

Сервис, который отвечает за 200 мс на одном запросе, может упасть на 50 одновременных. Проверьте это до запуска интеграции.

Инструменты стресс-теста

ИнструментКогда братьОграничения
Apache JMeterСценарии из нескольких запросов, отчёты по перцентилямТяжёлый интерфейс, нужна Java
k6Сценарий пишется кодом, удобно хранить в репозиторииТолько командная строка
Postman RunnerБыстро прогнать коллекцию N разЭто не настоящая параллельная нагрузка

Начните с 5 потоков, затем 20, затем 50. Смотрите на рост времени ответа и на появление ошибок 500 и 503. Тест гоняйте только на копии — запись документов под нагрузкой создаст тысячи тестовых заказов.

Повторное использование сеансов

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

У объекта HTTP-сервиса в конфигурации есть свойство «Повторное использование сеансов» и время жизни сеанса. Те же параметры задают в default.vrd:

<httpServices publishByDefault="false">
  <service name="API" rootUrl="api" enable="true"
           reuseSessions="autouse" sessionMaxAge="20"
           poolSize="10" poolTimeout="5"/>
</httpServices>
  • reuseSessions="autouse" — платформа сама держит пул сеансов;
  • poolSize — сколько сеансов держать;
  • sessionMaxAge — время жизни сеанса в секундах.

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

Пул занимает лицензии и память рабочего процесса. Для 10 сеансов в пуле нужно 10 свободных клиентских лицензий на сервере.

Безопасность HTTP-сервиса: что проверить до публикации

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

  • 🔒 Только HTTPS снаружи. Базовая авторизация передаёт логин и пароль в каждом запросе в кодировке Base64 — это не шифрование.
  • 👤 Отдельный пользователь с минимальной ролью. Не давайте сервису «Полные права» ради того, чтобы «заработало».
  • 🔑 Не храните пароль в строке ib файла default.vrd. Тогда вход без пароля получает любой, кто знает адрес.
  • 🧾 Не возвращайте клиенту ПодробноеПредставлениеОшибки() — только общий текст и идентификатор запроса.
  • ✅ Проверяйте входные данные: тип, длину строк, допустимые значения. Не подставляйте параметры URL в текст запроса склейкой строк — передавайте через Запрос.УстановитьПараметр().
  • 📏 Ограничьте размер тела и частоту запросов на веб-сервере (IIS, Apache или nginx перед ним). Защита от перебора паролей настраивается там же.
  • 🙈 Не пишите в журнал заголовок Authorization, токены и персональные данные целиком.
Перед выводом HTTP-сервиса в продакшн
Выполнено: 0 / 7

Строку debug в рабочей публикации не оставляйте: веб-сервер будет пытаться подключиться к серверу отладки, а при открытом порте посторонний сможет подключиться к сеансам сервиса.

Ошибки HTTP-сервисов 1С: коды ответа и причины

Код ответа — первая подсказка, где искать. Ошибка до вашего модуля и ошибка внутри него лечатся по-разному.

Диагностика: выберите симптом

Если не помогло

  1. Отправьте тот же запрос с самого веб-сервера на localhost. Работает — проблема в сети, прокси или брандмауэре между клиентом и сервером.
  2. Временно замените тело метода на возврат Новый HTTPСервисОтвет(200). Не работает даже так — проблема в публикации или авторизации, а не в вашем коде.
  3. Посмотрите журнал самого веб-сервера: в IIS — логи сайта в C:\inetpub\logs\LogFiles, в Apache — error.log. Ошибки загрузки модуля расширения видны только там.

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

Можно ли отлаживать HTTP-сервис в файловой базе?
Да. Код выполняется в процессе веб-сервера, поэтому отладку включают в default.vrd и в Конфигураторе так же, как для клиент-серверной базы. Ключи службы сервера 1С в этом случае не нужны.
Почему точка останова в модуле сервиса не срабатывает?
Чаще всего в Конфигураторе не настроено автоматическое подключение для HTTP-сервисов, не перезапущен веб-сервер после правки default.vrd или порт 1550 закрыт брандмауэром на машине разработчика.
Как узнать, сколько времени выполняется каждый вызов в продакшне?
Включите в журнале веб-сервера поле с длительностью запроса или отберите события CALL в техжурнале по имени сервиса. Отладчик и замер производительности в рабочей базе не используют.
Нужна ли отдельная лицензия на каждый запрос к HTTP-сервису?
Каждый одновременно открытый сеанс сервиса занимает клиентскую лицензию. Последовательные запросы с закрытием сеанса лицензии освобождают, пул повторного использования держит их занятыми.
Чем HTTP-сервис отличается от веб-сервиса при отладке?
Механизм отладки общий, но HTTP-сервис отдаёт произвольный JSON или XML, а веб-сервис работает по SOAP с WSDL-описанием. Для HTTP-сервиса достаточно curl, для веб-сервиса удобнее SoapUI.