diamond АШ Tlg

1С ERP: Как гиперактивные плановики могут обвалить сервер

Разбор кейса: поступил заказ на расследование причин того, почему сервер периодически подвергается мощной нагрузке, длящейся часами. Следствие вывело не на самого себя, а на плановиков.

Кроме высокой нагрузки на сервер, также отмечалось экстремально долгое проведение планов, с низкой вероятностью успеха. Как полагается в таких случая, был настроен сбор метрик и технологический журнал. ТЖ сразу вывел на ошибку блокировок, а метрики показали перегрузку дискового ввода-вывода на СУБД. При просмотре кода в общем модуле Планирование обнаружилась довольно интересная и суровая блокировка: исключительная и целиком на весь регистр сведений ЗамещениеПланов:

Процедура ВыполнитьФоновоеПроведенияПлана(ПараметрыЗадания) Экспорт

    /// вырезан несущественный фрагемент          

    НачатьТранзакцию();
	
    Попытка
        Блокировка = Новый БлокировкаДанных;
        ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ЗамещениеПланов");
        ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
        Блокировка.Заблокировать();
    
        Запрос = Новый Запрос();
        Запрос.Текст = 
        "ВЫБРАТЬ РАЗЛИЧНЫЕ
        |	ЗамещениеПланов.ЗамещенныйПлан
        |ИЗ
        |	РегистрСведений.ЗамещениеПланов КАК ЗамещениеПланов
        |ГДЕ
        |	(ЗамещениеПланов.КЗамещению
        |			ИЛИ ЗамещениеПланов.КОтменеЗамещения)";
        Выборка = Запрос.Выполнить().Выбрать();
    
        ЗафиксироватьТранзакцию();
    Исключение
        ОтменитьТранзакцию();

        /// вырезан несущественный фрагемент          
    
        ВыполнитьФоновоеПроведенияПлана(ПараметрыЗадания);
        Возврат;
    КонецПопытки;

    ЗамещениеВыполнено = Истина;

    Пока Выборка.Следующий() Цикл
        ПараметрыЗадания.Вставить("ЗамещенныйПлан", Выборка.ЗамещенныйПлан);
        ВыполнитьПроведенияПлана(ПараметрыЗадания);
        ЗамещениеВыполнено = Ложь;
    КонецЦикла;

    Если Не ЗамещениеВыполнено Тогда
        ВыполнитьФоновоеПроведенияПлана(ПараметрыЗадания);
    КонецЕсли;

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

Авторы модуля планирования ERP предполагали видимо, что запрос вернет всего несколько строк и в продолжении транзакции (регистр остается заблокированным) проведутся 2-5 документов. Но если временно убрать исключительную блокировку и во время высокой нагрузки выполнить в консоли это запрос, то он возвращал более 380 строк! Кстати для запроса нет подходящего индекса, но в данном случае это ерунда - потеря всего 0.5 секунд. Этот кусок кода вызывался при каждом проведении документа планов. Но что ещё интереснее, он вызывается при открытии форм списка документов планирования (закупки, продаж, производства), и тем, кому это показалось мало - ещё и по таймеру через каждый час! Чтоб не быть голословным, вот кусок кода формы списка:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    КонтрольЗамещенияПланов();
    ПодключитьОбработчикОжидания("КонтрольЗамещенияПланов", 3600);
КонецПроцедуры

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

Что же плановики сделали, чтобы добиться таких успехов? Здесь сыграло сразу несколько факторов:

  • Очень длинный горизонт планирования. На предприятии внутреннним стандартом введено годовое оперативное планирование с разбивкой по месяцам. Разделения на оперативные и прочие виды планов не было;
  • Все планы спускает в режиме онлайн генеральный покупатель продукции (конвейерное производство);
  • Каждый документ соответственно вводился на год вперед, в режиме замещения. Так научили франчи при внедрении и был документирован даже процесс, отходить от которого никто не смел;
  • В качестве примера, в каждом документе плана продаж было более 500 строк товаров, итого с учетом разбиения на месяцы технически их было более 6 тысяч;
  • Планы продаж на год вперед в качестве оперативного вводились от 1 до 5 штук в день, кроме выходных и праздничных дней. Отсюда и достижение в виде длины цепочки замещений более 380 документов. Закупщики и производство реагироваля на это вяло и их вклад был ничтожным;
  • У всех плановиков постоянно была открыта форма списка документов планирования;
  • Архитектура подсистемы планирования в ERP. Авторы явно не расчитывали на его использование в промышленных масштабах.
  • Серверы не тянули такую нагрузку.
План продаж План продаж

Как же побороть проблему? В первую очередь рекомендовал продажам умерить излишнюю активность и вводить максимум 1 документ планов в день, т.к. смысл мгновенного реагирования плановиком на поступающие изменения объяснить никто не смог. Во-вторую очередь, не замещать планы на такие длинные сроки вперед, а только на актуальные месяцы, где реально вносились корректировки, в идеале только на 1 месяц.

В долгосрочной перспективе рекомендовано было изучить возможность перестроения процесса планирования, разбив его на несколько видов и выделив оперативный отдельно. С учётом требований генерального потребителя, конечно. В настоящее время вводят замещения на 2-6 месяцев вперед, цепочки замещений имеют длину в 20-40 документов, но сервер уже спокойно переваривает такое, поэтому тот самый запрос с блокировкой возвращает 0 строк. До рекомендации усилить серверные мощности дело не дошло. Ну и отлично.