Почему платформа 1С 8.3.15.1830 грузит процессор на сервере под 100% и как это исправить

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

При обновлении технологической платформы 1С:Предприятие предприятия нередко сталкиваются с ситуацией, когда стабильно работающая годами система начинает вести себя непредсказуемо. Типичный сценарий: обновили платформу с «тихой» версии (например, 8.3.12.1790) на более свежую (например, 8.3.15.1830) ради совместимости с обновленными конфигурациями (такими как Зарплата и Управление Персоналом), и сервер приложений 1С мгновенно уходит в пиковую нагрузку. При этом рабочий процесс rphost утилизирует CPU на 100%, пользователи жалуются на зависания, а сервер баз данных (MS SQL Server или PostgreSQL) практически полностью простаивает.

В этой статье мы подробно разберем, почему возникает эта проблема, как локализовать «прожорливый» запрос или фоновое задание и какими методами можно нормализовать работу сервера без отката на старую версию платформы.

В чем причина аномальной нагрузки на сервер приложений?

Когда СУБД «отдыхает», а сервер приложений 1С загружен на максимум, это главный признак того, что тяжелые вычислительные операции (такие как соединение таблиц, группировка, сортировка или сопоставление типов) выполняются не силами базы данных, а непосредственно в оперативной памяти процесса rphost. Рассмотрим основные технические причины, почему на платформе 8.3.15.1830 этот эффект проявляется наиболее остро.

1. Изменение логики транслятора SDBL (перенос вычислений на сторону сервера 1С)

Начиная с версий 8.3.13–8.3.15, разработчики платформы существенно изменили и оптимизировали внутренний транслятор запросов SDBL. Его задача — переводить запросы, написанные на встроенном языке 1С, в SQL-запросы, понятные для конкретной СУБД. Однако у этой оптимизации есть обратная сторона. Если в конфигурации используется сложный, неоптимальный или переписанный запрос, старый транслятор платформы 8.3.12 мог транслировать его в один тяжелый SQL-запрос. СУБД выполняла его долго, но за счет собственных индексов и оптимизатора планов запросов все же завершала операцию.

Новый транслятор SDBL в версии 8.3.15 при попытке обработать аналогичный запрос может принять решение разбить его на несколько простых подзапросов. Платформа быстро забирает из базы данных огромные объемы «сырых» промежуточных данных в память сервера приложений, а финальное соединение и фильтрацию начинает выполнять локально силами процессора сервера 1С. В результате SQL-сервер моментально отдает данные и засыпает, а процесс rphost уходит в бесконечный цикл обработки массивов информации, съедая 100% CPU.

2. Разыменование полей составного типа данных

В релизах платформы ветки 8.3.15 присутствует критическая особенность обработки полей составного типа. Проанализируем ситуацию: если в запросе или динамическом списке происходит обращение через точку к реквизитам поля составного ссылочного типа (например, ДокументОбъект.Контрагент.Наименование, где реквизит Контрагент может быть как справочником Контрагенты, так и справочником ФизическиеЛица), платформа генерирует левые соединения (LEFT JOIN) ко всем таблицам, входящим в этот составной тип.

В версии 8.3.15.1830 подготовка, сопоставление типов метаданных и сериализация этих выборок на стороне сервера приложений стали требовать в разы больше процессорного времени. Если в цикле или фоновом задании такой запрос выполняется многократно, сервер 1С зависает.

3. Проблемы маршалинга при COM-обмене в фоновых заданиях

Если в системе настроен обмен данными (например, между «Управление торговлей 10.3» и «Зарплата и Управление Персоналом») посредством COM-соединения, запущенного из-под фонового задания, то платформа 8.3.15 накладывает свои ограничения. В этой версии были изменены механизмы сериализации данных и передачи COM-объектов между потоками операционной системы. Попытка передать большую таблицу значений или выборку через COM-порт вызывает утечки памяти и лавинообразный рост нагрузки на CPU.

4. Паразитная нагрузка в «пустой» базе данных

Когда регламентные или фоновые задания выполняются в информационной базе, где нет активных пользователей (например, ночью или при работе исключительно через COM/Web-сервисы), платформа 8.3.15 ведет себя не так, как 8.3.12. При каждом старте фонового задания в отсутствие активных сеансов рабочий процесс rphost вынужден заново компилировать и загружать в память всю конфигурацию метаданных, выполнять процедуру и полностью выгружать ее. Если фоновые задания запускаются часто (раз в несколько секунд или минут), процесс инициализации конфигурации начинает непрерывно нагружать процессор.

---

Пошаговый алгоритм локализации проблемного запроса

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

Шаг 1. Поочередное отключение фоновых заданий

Самый простой и быстрый способ локализации «виновника» — это управление регламентными заданиями. Выполним следующие действия:

  1. Запустим базу данных в режиме «1С:Предприятие» под правами администратора.
  2. Откроем консоль регламентных заданий (в типовых конфигурациях или через внешнюю обработку).
  3. Отключим все активные регламентные задания. Если нагрузка на CPU сразу же упала до штатных значений, значит, проблема действительно в одном из них.
  4. Включим регламентные задания по одному с интервалом в несколько минут, контролируя загрузку процессора в диспетчере задач сервера. Как только после включения очередного задания CPU подскочит до 100%, мы найдем проблемный процесс.

Шаг 2. Настройка Технологического Журнала (ТЖ) для детального анализа

Если ручной поиск не принес результатов или нагрузка носит плавающий характер, настроим сбор технологического журнала 1С. Нам понадобятся события SDBL (запросы к внутренней СУБД 1С) и DBMSSQL / DBPOSTGRS (запросы к SQL-серверу). Создадим файл конфигурации технологического журнала logcfg.xml в каталоге установки платформы (например, C:\Program Files\1cv8\conf\) со следующим содержимым:


<config xmlns="http://v8.1c.ru/v8/tech-log">
    <log location="C:\v8logs\db_queries" history="2">
        <event>
            <eq property="Name" value="SDBL"/>
        </event>
        <event>
            <eq property="Name" value="DBMSSQL"/>
        </event>
        <property name="all"/>
    </log>
</config>

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

---

Способы устранения проблемы и оптимизации запросов

После того как проблемный запрос во встроенном языке 1С найден, его необходимо модифицировать так, чтобы транслятор платформы 8.3.15 мог корректно передать его выполнение на уровень СУБД.

Решение 1. Использование конструкции ВЫРАЗИТЬ (CAST)

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


ВЫБРАТЬ
    Продажи.ДокументРегистратор.Номер КАК НомерДокумента,
    Продажи.ДокументРегистратор.Дата КАК ДатаДокумента
ИЗ
    РегистрНакопления.Продажи КАК Продажи

Поскольку поле ДокументРегистратор может содержать десятки видов документов, платформа 8.3.15 попытается соединить таблицу регистра со всеми таблицами этих документов. Чтобы оптимизировать этот узел, обязательно используем явное приведение типов с помощью конструкции ВЫРАЗИТЬ():


ВЫБРАТЬ
    ВЫБОР 
        КОГДА Продажи.ДокументРегистратор ССЫЛКА Документ.РеализацияТоваровУслуг 
            ТОГДА ВЫРАЗИТЬ(Продажи.ДокументРегистратор КАК Документ.РеализацияТоваровУслуг).Номер
        КОГДА Продажи.ДокументРегистратор ССЫЛКА Документ.ОтчетОРозничныхПродажах 
            ТОГДА ВЫРАЗИТЬ(Продажи.ДокументРегистратор КАК Документ.ОтчетОРозничныхПродажах).Номер
    КОНЕЦ КАК НомерДокумента
ИЗ
    РегистрНакопления.Продажи КАК Продажи

Такой подход гарантирует, что СУБД выполнит строго определенные соединения, а сервер 1С избавится от необходимости сопоставлять типы в памяти.

Решение 2. Индексация временных таблиц

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

Добавим индексирование при создании временной таблицы:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Товар,
    Номенклатура.Код КАК Код
ПОМЕСТИТЬ ВТ_Товары
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Услуга = ЛОЖЬ

ИНДЕКСИРОВАТЬ ПО
    Товар
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Товары.Код,
    Остатки.КоличествоОстаток
ИЗ
    ВТ_Товары КАК ВТ_Товары
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
        ПО ВТ_Товары.Товар = Остатки.Номенклатура

Индексирование поля Товар во временной таблице позволит СУБД моментально сопоставить данные, исключив паразитную нагрузку на CPU сервера приложений.

Решение 3. Использование разных версий платформ для разных баз

Если переписанный код УТ 10.3 слишком объемен, а ресурсы на его рефакторинг ограничены, можно прибегнуть к архитектурному решению, предложенному системными администраторами. На одном физическом сервере можно одновременно запустить две разные версии службы сервера 1С:

Единственная сложность данного подхода заключается в COM-обмене между базами. Так как версии платформ будут отличаться, прямые COM-соединения могут вызывать конфликты библиотек классов. Рекомендуется перевести обмен данными на более современные и независимые протоколы, такие как Web-сервисы (SOAP) или HTTP-сервисы. Это не только решит проблему с падением производительности, но и повысит общую отказоустойчивость информационной системы.

← На главную