При интеграции систем через веб-сервисы (SOAP) и HTTP-сервисы (REST) разработчики часто сталкиваются с необходимостью предварительно проверить доступность удаленной базы. Вызов тяжелой рабочей операции, которая формирует массив данных или проводит документы, может зависнуть на минуты, если целевой сервер перегружен или сеть работает нестабильно. Разберем, как устроен механизм проверки связи, почему базовая реализация из документации не всегда безопасна в реальной инфраструктуре и как защитить интеграцию от ложных срабатываний и кэширования.
Главная цель метода Ping — быстрое выяснение доступности узла перед выполнением основных задач. Стандарты разработки платформы 1С рекомендуют применять двухэтапный сценарий подключения, если расчетное время выполнения целевой операции превышает 20 секунд. Проанализируем, как работает эта схема:
WSПрокси с коротким фиксированным таймаутом (рекомендуется устанавливать таймаут в районе 7 секунд).Ping. Если база 1С недоступна, остановлен веб-сервер или разорван сетевой канал, программа мгновенно возвращает ошибку по таймауту, не заставляя пользователя или фоновое задание ждать завершения длительного ожидания.WSПрокси с длительным таймаутом (например, несколько сотен секунд), и уже через него отправляются основные пакеты данных.В Библиотеке стандартных подсистем (БСП) эта механика заложена в функцию WSПрокси общего модуля ОбщегоНазначения, которая умеет выполнять предварительный опрос доступности перед возвратом рабочего объекта.
Посмотрим на классический пример операций, который часто приводят в типовых методиках:
Функция Ping()
Возврат ""; // Проверка связи
КонецФункции
Функция Pong(Знач Параметр)
Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Привет, %1'"), Параметр);
КонецФункции
На первый взгляд реализация выглядит максимально простой и быстрой: функция возвращает пустую строку или булево значение Истина. Однако на практике такая схема таит в себе серьезную опасность при работе через промежуточные узлы сети. Выясним причину этой проблемы.
Если между клиентом и информационной базой 1С установлены промежуточные прокси-серверы, балансировщики нагрузки (например, Nginx) или шлюзы безопасности, статический ответ вида "" или 200 OK может быть закэширован. В такой ситуации база 1С или служба кластера серверов могут полностью выйти из строя, но промежуточный прокси-сервер продолжит возвращать клиенту сохраненный ранее ответ. В результате клиент ошибочно считает, что сервис функционирует нормально.
Чтобы гарантировать, что ответ сформирован работающим экземпляром 1С именно в момент вызова, результат функции должен быть динамическим. Самый простой и надежный вариант — возвращать точное текущее время информационной базы. Посмотрим на пример реализации операции на стороне веб-сервиса:
Функция Ping()
// Возвращаем универсальное системное время для исключения проблем с часовыми поясами
Возврат УниверсальноеВремя(ТекущаяДатаСеанса());
КонецФункции
Разберем логику проверки на стороне вызывающей системы. Клиент принимает значение времени и проверяет два критерия: ответ не должен быть пустым, а разница между временем сервера и временем клиента не должна выходить за разумные рамки (с поправкой на сетевые задержки):
ПараметрыПодключения = Новый Структура("Таймаут", 7);
ПроксиДляПроверки = ОбщегоНазначения.WSПрокси(Определения, "http://example.com/ws", "ExchangeService", "ExchangePort", ПараметрыПодключения);
Попытка
ВремяСервера = ПроксиДляПроверки.Ping();
Если Не ЗначениеЗаполнено(ВремяСервера) Тогда
ВызватьИсключение НСтр("ru = 'Сервер вернул пустой ответ при проверке связи.'");
КонецЕсли;
// Дополнительно можно проверить разницу времени или зафиксировать факт смены значения
ОтветКорректен = Истина;
Исключение
ОтветКорректен = Ложь;
ЗаписьЖурналаРегистрации("Интеграция.ПроверкаСвязи", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Еще более надежный подход — заставить сервер возвращать то значение, которое отправил сам клиент. В этом случае даже при рассинхронизации часов между серверами клиент точно знает, какой ответ ожидается, а промежуточные прокси-серверы не смогут вернуть старый кэш из-за уникальности входящего параметра.
Рассмотрим реализацию метода на стороне веб-сервиса:
Функция Pong(Знач ИдентификаторЗапроса)
// Возвращаем полученный токен без изменений
Возврат ИдентификаторЗапроса;
КонецФункции
Посмотрим на клиентский код вызова:
ТокенПроверки = Строка(Новый УникальныйИдентификатор);
Попытка
ОтветСервера = ПроксиДляПроверки.Pong(ТокенПроверки);
Если ОтветСервера <> ТокенПроверки Тогда
ВызватьИсключение НСтр("ru = 'Получен некорректный ответ (возможно кэширование шлюзом).'");
КонецЕсли;
Исключение
// Обработка недоступности сервиса
КонецПопытки;
При использовании HTTP-сервисов управление кэшированием становится еще более прозрачным, так как разработчик имеет прямой доступ к HTTP-заголовкам объекта HTTPСервисОтвет. Разберем правильное формирование ответа при реализации проверки доступности:
Функция PingGET(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
// Запрещаем кэширование на стороне браузеров и промежуточных прокси
Ответ.Заголовки.Вставить("Cache-Control", "no-store, no-cache, must-revalidate");
Ответ.Заголовки.Вставить("Pragma", "no-cache");
Ответ.Заголовки.Вставить("Expires", "0");
// Формируем динамическое тело ответа
Ответ.УстановитьТелоИзСтроки(Формат(ТекущаяУниверсальнаяДатаВМиллисекундах(), "ЧГ=0"));
Возврат Ответ;
КонецФункции
Полезный прием для HTTP-запросов: для проверки состояния можно использовать HTTP-метод HEAD вместо GET. Метод HEAD обрабатывает маршрут на сервере и возвращает статусный код (например, 200 OK) без передачи тела, что экономит сетевой трафик при постоянном мониторинге.
Важно помнить об архитектурных ограничениях платформы при организации внешнего мониторинга доступности:
default.vrd настраиваются параметры пула соединений. Если сеанс создается заново (холодный старт), выполнение метода Ping может занять от 1 до 3 секунд из-за полной инициализации параметров сеанса, что при жестком таймауте приведет к ложному срабатыванию ошибки.GET /ws/ExchangeService?wsdl. Веб-сервер отдает описание без старта сеанса в базе 1С и без захвата лицензий.