Можно ли выполнить код 1С в момент старта службы сервера 1С:Предприятие?

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

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

Почему в самой 1С нет встроенного события «При старте службы»

Проанализируем архитектуру серверной части платформы 1С:Предприятие. Процесс службы сервера ragent отвечает за запуск менеджера кластера rmngr и рабочих процессов rphost. Служба сервера функционирует на уровне операционной системы и управляет ресурсами кластера в целом, не привязываясь к конкретной информационной базе. В одном кластере может быть зарегистрировано множество баз, а может не быть ни одной.

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

Разберем основные практические варианты решения данной задачи.

Вариант 1. Запуск по событию Windows Event Viewer через планировщик задач

Рассмотрим классический способ для серверов под управлением ОС Windows. При запуске любой службы диспетчер управления службами (Service Control Manager) фиксирует событие в системном журнале. Мы можем привязать выполнение скрипта к этому событию с помощью стандартного планировщика задач Windows (Task Scheduler).

  1. Откроем Просмотр событий (Event Viewer) и перейдем в журнал Система (System).
  2. Найдем событие с источником Service Control Manager и идентификатором Event ID 7036 («Служба перешла в состояние Работает»).
  3. Создадим в Планировщике задач Windows новую задачу, указав триггер «По событию»:

    Журнал: System

    Источник: Service Control Manager

    Код события: 7036

    В XML-фильтре триггера уточним имя конкретной службы 1С (например, 1C:Enterprise 8.3 Server Agent), чтобы задача не реагировала на запуск сторонних служб.

  4. В качестве действия укажем запуск управляющего скрипта (PowerShell, VBScript или OneScript).

Посмотрим на пример PowerShell-скрипта, который ожидает полную инициализацию кластера и подключается к базе через COM-соединение для выполнения процедуры:


# Пауза для инициализации рабочих процессов rphost
Start-Sleep -Seconds 15

$ServerName = "localhost"
$BaseName = "TradeManagement"
$User = "Admin"
$Password = "SecretPassword"

try {
    $Connector = New-Object -ComObject "V83.COMConnector"
    $Connection = $Connector.Connect("Srvr='$ServerName';Ref='$BaseName';Usr='$User';Pwd='$Password';")
    
    # Вызов экспортной функции из общего модуля
    $Connection.ОбщийМодульСервера.ВыполнитьДействияПослеРестарта();
    Write-Host "Код 1С успешно выполнен."
}
catch {
    Write-Error "Ошибка подключения к 1С: $_"
}

Вариант 2. Использование unit-файлов systemd в Linux

Если сервер 1С работает под управлением ОС Linux (Ubuntu, Astra Linux, ALT Linux, RedOS), разберем настройку через подсистему инициализации systemd. В конфигурационном unit-файле службы 1С предусмотрена специальная директива ExecStartPost, которая выполняется сразу после успешного запуска основного процесса.

  1. Откроем для редактирования unit-файл службы (или создадим переопределение через systemctl edit srv1cv8-8.3.XX.XXXX@.service).
  2. Добавим директиву ExecStartPost с указанием пути к нашему bash- или python-скрипту:
    
    [Service]
    ExecStartPost=/opt/scripts/after_1c_start.sh
    
  3. Применим изменения командой systemctl daemon-reload.

Внутри скрипта after_1c_start.sh мы можем вызвать запуск внешней обработки через пакетный режим толстого/тонкого клиента или отправить HTTP-запрос к опубликованной базе:


#!/bin/bash
# Ожидаем готовность кластера к приему запросов
sleep 20

# Пакетный запуск 1С с выполнением обработки
/opt/1cv8/x86_64/8.3.24.1548/1cv8 ENTERPRISE \
  /S "appserver/production_base" \
  /N "ServiceUser" \
  /P "Pass123" \
  /Execute "/opt/scripts/OnServerStart.epf" \
  /DisableStartupMessages

Вариант 3. Вызов HTTP-сервиса базы данных

Разберем современный и надежный архитектурный подход. Если информационная база 1С опубликована на веб-сервере (Apache, IIS, Nginx), скрипт после старта службы отправляет простой HTTP-запрос на служебный HTTP-сервис 1С.

Посмотрим на пример кода HTTP-сервиса в конфигурации 1С:


Функция ОбработатьСтартСлужбы(Запрос)
    
    // Выполняем требуемую серверную логику
    РегламентныеПроцедурыСервера.ИнициализироватьКэш();
    РегламентныеПроцедурыСервера.ОтправитьУведомлениеОПерезапуске();
    
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.УстановитьТелоИзСтроки("OK", КодировкаТекста.UTF8);
    Возврат Ответ;
    
КонецФункции

Преимущество этого метода заключается в том, что скрипту ОС не требуется хранить COM-коннекторы или запускать тяжелый клиентский процесс 1С — достаточно выполнить вызов утилитой curl или командлетом Invoke-RestMethod.

Вариант 4. Определение перезапуска внутри 1С через регламентное задание

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

  1. Создадим регистр сведений ПараметрыРаботыСервера с ресурсом ИдентификаторПроцесса (число).
  2. В процедуре регламентного задания получаем текущий PID процесса кластера (например, через WMI или чтение информации о сеансах) и сравниваем его с сохраненным значением.

Проанализируем пример кода для регламентного задания:


Процедура ПроверитьПерезапускСервера() Экспорт
    
    #Если Сервер И Не ВнешнееСоединение Тогда
        
        // Получаем PID текущего рабочего процесса
        ИмяПроцесса = "rmngr.exe";
        ТекущийPID = ПолучитьPIDПроцесса(ИмяПроцесса); 
        
        СохраненныйPID = Константы.ПоследнийPIDКластера.Получить();
        
        Если ЗначениеЗаполнено(ТекущийPID) И ТекущийPID <> СохраненныйPID Тогда
            
            // Сервер был перезапущен - выполняем целевую логику
            ОбработатьПерезапускСлужбыСервера();
            
            // Фиксируем новый PID
            Константы.ПоследнийPIDКластера.Установить(ТекущийPID);
            
        КонецЕсли;
        
    #КонецЕсли

КонецПроцедуры

Важный нюанс: ожидание готовности кластера (Warm-up)

Обратим особое внимание на частую ошибку при реализации внешних скриптов. Момент, когда служба ragent перешла в состояние «Работает», не означает, что кластер готов мгновенно исполнять код. Серверу 1С требуется время (от 10 до 60 секунд) для старта рабочих процессов rphost, подключения к СУБД и инициализации пространства памяти.

Любой скрипт запуска (через COM, HTTP или пакетный режим) обязательно должен содержать паузу (sleep) либо цикл повторных попыток с обработкой исключений, чтобы дождаться полной готовности кластера к обработке входящих подключений.

← На главную