Как ограничить количество одновременно работающих регламентных заданий в 1С?

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

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

Метод 1. Программная проверка количества активных заданий

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

Рассмотрим следующий фрагмент кода, который можно встроить в начало обработчика регламентного задания:


// Определяем параметры отбора для активных заданий
Отбор = Новый Структура;
Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);

// Получаем массив всех работающих в данный момент фоновых заданий
ФоновыеЗаданияПроверка = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);

// Устанавливаем лимит (например, не более 3 одновременно работающих заданий)
МаксимальноеКолвоЗаданий = 3;

Если ФоновыеЗаданияПроверка.Количество() > МаксимальноеКолвоЗаданий Тогда
    // Если лимит превышен, выходим из процедуры, не нагружая систему
    ЗаписьЖурналаРегистрации("РегламентныеЗадания.Лимит", 
        УровеньЖурналаРегистрации.Предупреждение, , , 
        "Превышен лимит одновременно работающих заданий. Запуск отменен.");
    Возврат;
КонецЕсли;

Этот метод хорош тем, что он прост в реализации. Однако у него есть нюанс: ФоновыеЗадания.ПолучитьФоновыеЗадания возвращает все активные задания в базе. Если в вашей системе много мелких и быстрых заданий (например, проверка почты), они могут «забивать» этот счетчик, мешая запуститься действительно важным тяжелым процессам. В таком случае в структуру отбора стоит добавить фильтр по имени регламентного задания или использовать ключевые слова.

Метод 2. Использование механизма «Семафоров» через Регистр сведений

Для более тонкого контроля, особенно когда нужно ограничивать не все задания подряд, а только определенные «тяжелые» типы (например, только обмены), мы можем применить механизм семафоров. Разберем по шагам, как это реализовать:

  1. Создадим непериодический регистр сведений АктивныеТяжелыеЗадания с одним измерением ИдентификаторЗадания (тип УникальныйИдентификатор).
  2. Перед началом выполнения основной логики задание делает запись в этот регистр.
  3. В блоке Попытка...Исключение...КонецПопытки (чтобы гарантировать очистку при ошибках) выполняется основная работа.
  4. В конце работы задание удаляет свою запись из регистра.

Посмотрим на пример реализации такой логики:


Процедура ВыполнитьТяжелыйОбмен() Экспорт
    
    // 1. Проверяем количество записей в нашем семафоре
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ РегистрСведений.АктивныеТяжелыеЗадания";
    Результат = Запрос.Выполнить().Выгрузить();
    
    Если Результат[0][0] >= 3 Тогда // Лимит 3
        Возврат; // Выходим, если уже работают 3 обмена
    КонецЕсли;

    // 2. Регистрируем начало работы
    МенеджерЗаписи = РегистрыСведений.АктивныеТяжелыеЗадания.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.ИдентификаторЗадания = ФоновыеЗадания.ТекущееФоновоеЗадание().УникальныйИдентификатор;
    МенеджерЗаписи.Записать();

    Попытка
        // 3. Выполняем основную логику (например, выгрузку 100 000 товаров)
        ВыполнитьВыгрузкуТоваров();
    Исключение
        // Логируем ошибку, если нужно
    КонецПопытки;

    // 4. Обязательно удаляем запись о себе
    МенеджерЗаписи.Удалить();

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

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

Метод 3. Очередь заданий в Библиотеке стандартных подсистем (БСП)

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

В этой подсистеме реализован диспетчер, который сам следит за тем, сколько заданий выполняется. Задания помещаются в таблицу, и специальный процесс («Распределитель») запускает их по мере освобождения ресурсов. Выясним преимущества этого подхода:

Метод 4. Настройка кластера серверов 1С

Иногда проблему можно решить на уровне системного администрирования, не прибегая к программированию. В консоли администрирования кластера серверов 1С (через оснастку MMC или утилиту ras) можно настроить параметры рабочих процессов rphost.

Проанализируем параметры, которые могут помочь:

Метод 5. Оптимизация логики самих заданий

Прежде чем ограничивать количество, стоит выяснить: а нельзя ли сделать сами задания «легче»? Как справедливо замечено в обсуждении, выгрузка 100 000 товаров целиком при каждом запуске — это неоптимально.

Разберем способы оптимизации:

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

← На главную