При реализации сложных алгоритмов, таких как формирование большого объема данных в XML, часто возникает потребность в распараллеливании задач. Разбиение общего процесса на несколько фоновых заданий кажется логичным решением, однако разработчики нередко сталкиваются с внезапным завершением процессов. Давайте разберем, почему это происходит и как правильно проектировать параллельную обработку в 1С.
В документации 1С нет фиксированного «магического числа», которое ограничивало бы общее количество фоновых заданий. Если система выдает сообщение об ошибке, связанной с завершением задания пользователем или системой, это почти всегда означает, что инфраструктура сервера достигла предела своих ресурсов. Рассмотрим основные причины возникновения таких ошибок:
РабочийПроцесс (rphost) имеет свои ограничения по памяти. Если в одном РабочемПроцессе запущено слишком много параллельных задач, он может выйти за установленные администратором лимиты и быть принудительно перезагружен кластером.Практика показывает, что запускать фоновые задания без оглядки на «железо» — не самая лучшая идея. Рассмотрим, как подобрать оптимальные параметры:
Разберем взаимосвязь между потоками и мощностью сервера. Основной принцип здесь следующий: количество одновременно выполняемых фоновых заданий не должно критически превышать количество логических процессоров сервера. Если сервер имеет 12 ядер с поддержкой Hyper-Threading (всего 24 логических процессора), то запуск 100 или 200 заданий одновременно является избыточным.
Для определения оптимального числа воспользуемся следующей логикой:
Чтобы избежать ошибок при формировании больших пакетов данных, проанализируем следующие подходы к организации кода:
1. Использование механизма ключей
Если нам необходимо, чтобы определенные задачи не конфликтовали друг с другом, используем Ключ задания. При вызове метода ФоновыеЗадания.Выполнить() можно передать параметр Ключ, что позволит платформе контролировать количество однотипных заданий.
2. Ограничение количества через очередь
Рассмотрим пример того, как мы можем контролировать количество заданий программно. Вместо того чтобы «выстреливать» 100 заданиями одновременно, будем отслеживать их количество:
Функция ПолучитьКоличествоАктивныхЗаданий(ИмяМетода)
МассивЗаданий = ФоновыеЗадания.ПолучитьФоновыеЗадания(Новый Структура("Состояние", СостояниеФоновогоЗадания.Активно));
Счетчик = 0;
Для Каждого Задание Из МассивЗаданий Цикл
Если Задание.МетодИмени = ИмяМетода Тогда
Счетчик = Счетчик + 1;
КонецЕсли;
КонецЦикла;
Возврат Счетчик;
КонецФункции;
3. Распределение нагрузки по рабочим серверам
Если сервер 1С работает в кластере, мы можем использовать настройку ТребованияНазначенияФункциональности. Мы имеем возможность вынести «тяжелые» фоновые задания на отдельный, более мощный рабочий сервер кластера. Это освободит основные рабочие процессы, с которыми взаимодействуют пользователи, и повысит общую стабильность системы.
Проанализировав ситуацию, мы пришли к выводу, что «научный тык» — это не самый эффективный путь. Если вы столкнулись с подобной проблемой, выполните следующие шаги:
EXCP и JOB. Это позволит увидеть реальную ошибку, которая становится причиной завершения задания (например, нехватка памяти или ошибка блокировки).РабочиеПроцессы через консоль администрирования кластера в момент пиковой нагрузки.Помните, что увеличение количества потоков не всегда приводит к ускорению. Часто, наоборот, избыточная параллельность замедляет работу всей системы из-за конкуренции за ресурсы. Оптимальная настройка позволит вам стабильно формировать даже самые большие XML-файлы без сбоев.