Как надежно определить имя сервера в фоновом задании 1С и защитить копию базы от выполнения обменов?

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

При переносе рабочих баз 1С на тестовые серверы для разработки, тестирования или обучения администраторы и программисты часто сталкиваются с опасной ситуацией. Если в коде прописаны регламентные задания, автоматические обмены или выгрузки данных во внешние системы, тестовая база может «по привычке» запустить эти процессы. Это приводит к замусориванию рабочей базы тестовыми данными или, что еще хуже, к отправке реальным клиентам тестовых писем и SMS.

Для предотвращения подобных ситуаций разработчики обычно используют проверку имени сервера. Однако стандартный метод получения строки соединения в фоновом задании преподносит неприятный сюрприз: вместо реального имени сервера он возвращает localhost. В этой статье мы подробно разберем, почему так происходит, и рассмотрим четыре надежных способа обойти это ограничение.

Выясняем причину: почему возвращается localhost?

Для начала проанализируем поведение платформы «1С:Предприятие». В обычном клиентском сеансе вызов функции СтрокаСоединенияИнформационнойБазы() возвращает строку подключения, которую ввел пользователь в своем стартере 1С (например, Srvr="prod-server";Ref="work_db";). Это происходит потому, что инициатором соединения выступает клиентское приложение.

В фоновом задании ситуация принципиально иная:

  1. Клиентское приложение отсутствует. Задание выполняется непосредственно на сервере приложений 1С в контексте рабочего процесса rphost.
  2. Платформа берет адрес сервера из настроек самого кластера, где база часто регистрируется локально (через loopback-адрес localhost или 127.0.0.1).
  3. В результате функция СтрокаСоединенияИнформационнойБазы() (и её обертки в БСП, такие как СоединенияИБКлиентСервер.ПутьКИнформационнойБазе()) внутри фонового задания возвращает строку вида localhost\имя_базы, что делает невозможным стандартную проверку по имени боевого сервера.

Ниже мы подробно разберем четыре практических способа решения этой проблемы.

Способ 1. Использование встроенной функции ИмяКомпьютера()

Это самый простой, быстрый и кроссплатформенный способ разделения рабочего и тестового контуров. Встроенная функция платформы ИмяКомпьютера() при выполнении на стороне сервера (а фоновые задания всегда выполняются на сервере) возвращает сетевое имя (NetBIOS-имя) физического или виртуального сервера, на котором запущен рабочий процесс rphost.

Даже если в настройках кластера обеих баз прописан localhost, физические имена серверов операционной системы (например, под управлением Windows или Linux) гарантированно будут отличаться.

Рассмотрим пример реализации такой проверки в коде регламентного задания:


Процедура ВыполнитьОбменДанными() Экспорт
    
    // Получаем имя текущего сервера ОС в верхнем регистре
    ТекущийСервер = ВРег(ИмяКомпьютера());
    
    // Проверяем, соответствует ли сервер рабочему контуру
    Если ТекущийСервер <> "PROD-SERVER-OS" Тогда
        // Это тестовый контур. Логируем событие и прерываем выполнение обмена.
        ЗаписьЖурналаРегистрации("ОбменДанными.Блокировка",
            УровеньЖурналаРегистрации.Предупреждение,
            ,
            ,
            "Запуск обмена отменен: текущий сервер (" + ТекущийСервер + ") не является рабочим.");
        Возврат;
    КонецЕсли;
    
    // Далее идет основной код обмена...
    ИнтеграцияСВнешнимиСистемами.ВыгрузитьДанные();
    
КонецПроцедуры

Преимущества: Работает моментально, не зависит от настроек кластера 1С, корректно отрабатывает как на Windows, так и на Linux.

Способ 2. Использование механизмов БСП (Рекомендуемый стандарт)

Если ваша конфигурация построена на базе Библиотеки Стандартных Подсистем (БСП), вам не нужно писать собственные велосипеды для проверки имени сервера. В БСП встроен готовый и очень надежный механизм защиты от случайного запуска регламентных заданий в копиях баз.

Когда вы копируете базу на тестовый сервер и запускаете её, БСП автоматически фиксирует изменение параметров подключения (изменяется имя сервера, имя СУБД или имя самой базы). При первом входе администратора система выводит предупреждение: «Информационная база перемещена или восстановлена из резервной копии».

Если администратор выбирает вариант «Это копия информационной базы», БСП автоматически блокирует работу со всеми внешними ресурсами (блокируются регламентные задания, отправка почты, синхронизация данных, веб-сервисы).

Для проверки этой блокировки в коде вашего фонового задания достаточно вызвать стандартный метод БСП:


Процедура ВыполнитьОбменДаннымиБСП() Экспорт
    
    // Проверяем, разрешена ли работа с внешними ресурсами для данной базы
    Если НЕ ОбщегоНазначения.РазрешенаРаботаСВнешнимиРесурсами() Тогда
        // База определена как копия, блокируем выполнение транзакций во внешние системы
        ЗаписьЖурналаРегистрации("ОбменДанными.Блокировка",
            УровеньЖурналаРегистрации.Предупреждение,
            ,
            ,
            "Регламентное задание заблокировано, так как база запущена в режиме копии.");
        Возврат;
    КонецЕсли;
    
    // Безопасный запуск обмена
    ИнтеграцияСВнешнимиСистемами.ВыгрузитьДанные();
    
КонецПроцедуры

Преимущества: Это промышленный стандарт разработки под 1С. Механизм учитывает не только имя сервера, но и имя базы данных в СУБД, обеспечивая комплексную защиту.

Способ 3. Корректировка настроек кластера 1С:Предприятия

Если вам принципиально важно, чтобы функция СтрокаСоединенияИнформационнойБазы() возвращала красивое и реальное имя сервера во всех фоновых заданиях, необходимо устранить первопричину на уровне администрирования кластера 1С.

Разберем по шагам, как это сделать:

  1. Откройте утилиту «Администрирование серверов 1С:Предприятия».
  2. Перейдите к ветке вашего кластера и найдите раздел «Рабочие серверы».
  3. Обратите внимание на имя главного рабочего сервера. Скорее всего, там указано значение localhost.
  4. Откройте свойства этого сервера и замените localhost на реальное сетевое имя сервера (например, prod-app-server) или его статический IP-адрес. Нажмите «ОК».

В некоторых сложных случаях требуется ручная правка конфигурационных файлов кластера. Для этого:

  1. Остановите службу «Агента сервера 1С:Предприятие».
  2. Перейдите в каталог хранения настроек кластера (по умолчанию для Windows это C:\Program Files\1cv8\srvinfo).
  3. Найдите файлы реестра кластера 1cv8wsrv.lst и 1CV8Clst.lst.
  4. Откройте их в текстовом редакторе и замените все текстовые вхождения localhost на реальное сетевое имя сервера.
  5. Запустите службу Агента сервера 1С.

После выполнения этих действий фоновые задания будут корректно определять имя сервера через любые функции работы со строкой соединения.

Способ 4. Прямой запрос к операционной системе через COM (для Windows)

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

Посмотрим на пример кода, запрашивающий системную переменную %COMPUTERNAME%:


Функция ПолучитьИмяСервераЧерезОС()
    
    ИмяСервераОС = "";
    
    #Если Сервер Тогда
    Попытка
        // Создаем объект системной оболочки Windows Script Host
        WshShell = Новый COMОбъект("WScript.Shell");
        // Читаем системную переменную окружения COMPUTERNAME
        ИмяСервераОС = WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%");
    Исключение
        // Обработка исключения на случай, если запуск происходит на Linux
        // или у пользователя службы 1С нет прав на работу с COM-объектами
        ИмяСервераОС = "";
    КонецПопытки;
    #КонецЕсли
    
    Возврат ИмяСервераОС;
    
КонецФункции

Этот способ можно использовать в качестве резервного, если по каким-то причинам стандартные механизмы недоступны.

Резюме и рекомендации

Для надежной защиты вашей информационной системы мы рекомендуем комбинировать подходы:

← На главную