При работе с крупными базами данных 1С:Предприятие часто возникает ситуация, когда множество регламентных заданий запускаются одновременно. Если каждое из них выполняет тяжелую операцию — например, обмен данными с сайтом, выгрузку огромных прайс-листов или пересчет итогов, — серверные ресурсы (процессор, оперативная память и дисковая подсистема) могут быть полностью исчерпаны. Это приводит к значительному замедлению работы пользователей или даже к «зависанию» всей системы. В этой статье мы разберем, как программно и административно ограничить количество параллельно выполняемых процессов, чтобы обеспечить стабильную работу системы.
Самый простой и быстрый способ решить проблему — это добавить проверку в начало процедуры, которую вызывает регламентное задание. Мы можем проанализировать текущее состояние всех фоновых заданий в системе и, если их количество превышает допустимый предел, просто завершить выполнение нового задания. Проанализируем пример кода, который позволяет это реализовать.
Рассмотрим следующий фрагмент кода, который можно встроить в начало обработчика регламентного задания:
// Определяем параметры отбора для активных заданий
Отбор = Новый Структура;
Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
// Получаем массив всех работающих в данный момент фоновых заданий
ФоновыеЗаданияПроверка = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
// Устанавливаем лимит (например, не более 3 одновременно работающих заданий)
МаксимальноеКолвоЗаданий = 3;
Если ФоновыеЗаданияПроверка.Количество() > МаксимальноеКолвоЗаданий Тогда
// Если лимит превышен, выходим из процедуры, не нагружая систему
ЗаписьЖурналаРегистрации("РегламентныеЗадания.Лимит",
УровеньЖурналаРегистрации.Предупреждение, , ,
"Превышен лимит одновременно работающих заданий. Запуск отменен.");
Возврат;
КонецЕсли;
Этот метод хорош тем, что он прост в реализации. Однако у него есть нюанс: ФоновыеЗадания.ПолучитьФоновыеЗадания возвращает все активные задания в базе. Если в вашей системе много мелких и быстрых заданий (например, проверка почты), они могут «забивать» этот счетчик, мешая запуститься действительно важным тяжелым процессам. В таком случае в структуру отбора стоит добавить фильтр по имени регламентного задания или использовать ключевые слова.
Для более тонкого контроля, особенно когда нужно ограничивать не все задания подряд, а только определенные «тяжелые» типы (например, только обмены), мы можем применить механизм семафоров. Разберем по шагам, как это реализовать:
АктивныеТяжелыеЗадания с одним измерением ИдентификаторЗадания (тип УникальныйИдентификатор).Попытка...Исключение...КонецПопытки (чтобы гарантировать очистку при ошибках) выполняется основная работа.Посмотрим на пример реализации такой логики:
Процедура ВыполнитьТяжелыйОбмен() Экспорт
// 1. Проверяем количество записей в нашем семафоре
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ РегистрСведений.АктивныеТяжелыеЗадания";
Результат = Запрос.Выполнить().Выгрузить();
Если Результат[0][0] >= 3 Тогда // Лимит 3
Возврат; // Выходим, если уже работают 3 обмена
КонецЕсли;
// 2. Регистрируем начало работы
МенеджерЗаписи = РегистрыСведений.АктивныеТяжелыеЗадания.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ИдентификаторЗадания = ФоновыеЗадания.ТекущееФоновоеЗадание().УникальныйИдентификатор;
МенеджерЗаписи.Записать();
Попытка
// 3. Выполняем основную логику (например, выгрузку 100 000 товаров)
ВыполнитьВыгрузкуТоваров();
Исключение
// Логируем ошибку, если нужно
КонецПопытки;
// 4. Обязательно удаляем запись о себе
МенеджерЗаписи.Удалить();
КонецПроцедуры
Важный момент: использование регистра сведений надежнее, так как он позволяет учитывать задания только конкретных типов и сохранять информацию даже при кратковременных сбоях сервера приложений.
Если ваша конфигурация разработана на базе БСП (как большинство современных типовых решений), в ней уже заложен мощный механизм управления очередью. Вместо того чтобы настраивать расписание для каждого обмена отдельно, мы можем использовать подсистему ОчередьЗаданий.
В этой подсистеме реализован диспетчер, который сам следит за тем, сколько заданий выполняется. Задания помещаются в таблицу, и специальный процесс («Распределитель») запускает их по мере освобождения ресурсов. Выясним преимущества этого подхода:
Иногда проблему можно решить на уровне системного администрирования, не прибегая к программированию. В консоли администрирования кластера серверов 1С (через оснастку MMC или утилиту ras) можно настроить параметры рабочих процессов rphost.
Проанализируем параметры, которые могут помочь:
Прежде чем ограничивать количество, стоит выяснить: а нельзя ли сделать сами задания «легче»? Как справедливо замечено в обсуждении, выгрузка 100 000 товаров целиком при каждом запуске — это неоптимально.
Разберем способы оптимизации:
Подводя итог, наиболее надежным способом является комбинированный подход: использование программной проверки (семафора) для критически тяжелых заданий и переход на инкрементальные выгрузки (только измененных данных), что в совокупности снимет пиковую нагрузку с вашего сервера.