«1С тормозит» — это не техническое утверждение, а начало спора. Бизнес говорит «тормозит», подрядчик говорит «у нас всё в норме», и обе стороны правы, потому что меряют разное: пользователь меряет секунды до открытия документа, подрядчик — загрузку CPU на сервере.

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

Я собираю мониторинг 1С в составе своей платформы наблюдаемости и за последние месяцы прошёл все три уровня, включая пару очень неочевидных граблей на Windows. Ниже — разбор по уровням: что видно, чего не видно, чем это ловится и где именно молча ломается.

Дисклеймер: платформа называется Voltir, я её автор. Дальше — только открытые инструменты и грабли из практики: всё описанное собирается из prometheus_1C_exporter, windows_exporter, fluent‑bit и Grafana без всякого моего продукта.

Три уровня наблюдаемости 1С

Уровень 1. Операционная система. CPU, память, диск, сеть на серверах 1С и СУБД. Ставится за пять минут, node_exporter или windows_exporter. Отвечает на вопрос «железо ли виновато» и почти никогда — на вопрос «почему тормозит документ».

Уровень 2. Кластер серверов 1С. Сеансы, соединения, лицензии, рабочие процессы, регламентные задания, доступная производительность. Берётся снаружи через службу администрирования RAS/RAC, в базу лезть не нужно. Ставится за час. Отвечает на «что происходит в кластере прямо сейчас».

Уровень 3. Приложение. APDEX по ключевым операциям, ошибки прикладного кода, бизнес‑метрики. Живёт только внутри информационной базы, снаружи не достаётся ни при каких условиях. Требует изменений в базе клиента.

Ключевая мысль, ради которой стоит читать дальше: APDEX — это уровень 3. Всё, что вам покажут снаружи и назовут «APDEX», им не является.

Уровень 3, сразу: почему APDEX не бывает снаружи

APDEX (Application Performance Index) считается так: каждый замер операции сравнивается с целевым временем T. Если операция уложилась в T — она «удовлетворяет». Если в интервал от T до 4T — «терпимо». Больше 4T — «раздражает». Итог:

APDEX = (Satisfied + Tolerating / 2) / Total

Число от 0 до 1. У 1С это часть методики оценки производительности, и считается оно подсистемой «Оценка производительности» из БСП: в прикладном коде расставлены замеры ключевых операций («Проведение реализации», «Открытие формы заказа»), у каждой — своё T, замеры копятся в регистре, по ним строится история.

Отсюда два следствия, которые экономят месяцы:

  1. Целевое время T — это бизнес‑решение, а не техническая константа. «Проведение реализации за 3 секунды» — норма для одной компании и катастрофа для другой. APDEX без согласованного T не значит ничего, и никакой инструмент не подставит его за вас.

  2. Замер делается внутри операции, вокруг прикладного кода. Ни кластер, ни СУБД, ни ОС не знают, где у вас начинается и заканчивается «проведение реализации». Снаружи видно время серверного вызова — это другая величина: она не включает клиентскую часть и не совпадает с границами бизнес‑операции.

То, что снаружи иногда выдают за APDEX, — это либо среднее время серверного вызова, либо «доступная производительность» кластера (см. ниже). Обе метрики полезны. Обе — не APDEX.

Я рассматривал готовое решение с HTTP‑сервисом внутри базы, отдающим метрики в Prometheus, и отказался по трём типовым причинам: проект давно не развивается и совместимость со свежими 8.3.2x никто не проверял; в репозитории не указана лицензия, то есть включать его в продукт нельзя, чем бы оно ни было хорошо технически; и оно ломает онбординг — загрузка расширения в базу, публикация веб‑сервиса, роль и учётка, то есть час‑два ручной работы на базу и страх 1С‑ников клиента перед вмешательством в рабочую базу.

Рабочий путь к уровню 3, если он вам действительно нужен, я вижу такой: замеры БСП выгружаются во внешний файл или локальный endpoint на том же хосте, откуда их забирает уже стоящий там агент. Никаких веб‑сервисов наружу, никакой новой поверхности атаки. Но это отдельная работа и отдельный разговор с владельцем базы.

Уровень 2: что реально видно через RAS/RAC

Теперь то, что достаётся снаружи и стоит дёшево.

Кластер 1С — это несколько процессов: ragent (агент сервера, порт 1540, запускает остальное), rmngr (менеджер кластера, 1541, управляет, но прикладной код не исполняет) и rphost (рабочие процессы, исполняют код и обслуживают клиентов; их несколько). Отдельного процесса «доступа к СУБД» в кластере нет — rphost ходит в базу сам.

Администрируется всё это через RAS — фоновую службу администрирования (порт 1545), к которой подключается консольный клиент rac:

bash

ras cluster --port=1545 --service localhost:1540   # адрес ragent
rac 127.0.0.1:1545 cluster list
rac 127.0.0.1:1545 process list --cluster=<uuid>
rac 127.0.0.1:1545 session list --licenses --cluster=<uuid>

Дальше есть готовый экспортёр — LazarenkoA/prometheus_1C_exporter (MPL-2.0, что важно, если вы это распространяете). Он и дёргает rac, разбирая вывод. Набор метрик:

Метрика

Что даёт

Откуда

Что нужно

available_performance

доступная производительность каждого rphost + средние времена вызовов (avgcalltime, avgdbcalltime, avglockcalltime, avgservercalltime)

rac process list

доступ к RAS

session, sessions_data

сеансы кластера и их показатели

RAC

доступ к RAS

connect

соединения с кластером

RAC

доступ к RAS

client_lic

выданные клиентские лицензии

rac session list --licenses

доступ к RAS

shedule_job

блокировка регламентных заданий по каждой базе

rac infobase info

логин и пароль информационной базы

cpu, disk, processes

ресурсы хоста и процессов

локально с машины

Три практических вывода из этой таблицы:

Первое. cpu, disk, processes снимаются локально с той машины, где запущен экспортёр. Если у вас кластер из нескольких рабочих серверов, экспортёр нужен на каждом — иначе вы видите ресурсы одного из них и думаете, что видите кластер.

Второе. shedule_job требует учётные данные информационной базы (в экспортёре они не пишутся в конфиг, а забираются с внешнего endpoint'а, отдающего JSON с логином и паролем по каждой базе). Если метрика включена, а источник кредов не настроен, экспортёр падает на старте и уходит в рестарт‑цикл — то есть вы теряете не одну метрику, а все. Я эту метрику по умолчанию выключаю и включаю точечно, когда клиент готов дать учётку.

Третье, самое обидное. На сервере с лицензией разработчика вы не увидите session, sessions_data и client_lic — и это не поломка: активных сеансов нет, значит summary‑метрики не публикуются, серверные клиентские лицензии не выдаются. Я потратил на это время: дашборд выглядел абсолютно мёртвым, включая панели, у которых данные были. Причина оказалась не в метриках, а в дашборде — переменная host строилась через label_values(session, host), без сеансов список хостов пустой, и дашборд схлопывался целиком. Строить переменную нужно по метрике, которая есть всегда:

label_values(up{job="1c"}, host)

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

Про «доступную производительность»: как её читать и как не читать

Метрика available_performance (в консоли кластера — «доступная производительность») получается так: кластер периодически прогоняет на каждом рабочем процессе эталонный тестовый вызов, задействующий диск, память и процессор, и усредняет результат за последние несколько минут (в источниках встречается и 5, и 10 минут — не закладывайтесь на точную цифру). Результат — те самые «попугаи», по которым кластер выбирает, куда направить нового клиента: новые подключения идут на процесс с лучшей производительностью, а уже подключённые переезжают, только если сервер отказал или отличается от других в разы.

Что из этого следует для мониторинга:

  • Это относительная метрика. Сравнивать её между разными серверами и тем более между разными клиентами бессмысленно — она зависит от железа и от характера текущей нагрузки. Осмысленны две вещи: сравнение rphost'ов внутри одного кластера между собой и динамика во времени на одном процессе.

  • Просадка = процесс перегружен относительно соседей, и кластер уже начал уводить от него новых клиентов. Это ранний сигнал, до того как пользователи начнут жаловаться.

  • Алертить на абсолютное значение нельзя. Порог, работающий у одного клиента, у другого даст либо тишину, либо шторм. Работает алерт на просадку относительно собственного недавнего уровня.

И одна грабля, стоившая мне дублей алертов. Экспортёр мультиплексирует несколько разных величин в одну метрику, различая их лейблом type (собственно производительность, среднее время вызова, среднее время вызова СУБД и так далее). Если написать правило без фильтра по type, оно сработает сразу на нескольких рядах, отличающихся только этим лейблом, — и вы получите пачку алертов с разными fingerprint'ами про одну проблему:

yaml

# ПЛОХО: сработает на всех type сразу, дубли алертов
- alert: OneCPerformanceDegraded
  expr: available_performance < 30

# ХОРОШО: фильтр по type обязателен, порог — относительный
- alert: OneCPerformanceDegraded
  expr: available_performance{type="available"}
        < 0.5 * avg_over_time(available_performance{type="available"}[1d] offset 1d)
  for: 10m

Имя метрики здесь без префикса — это дефолт экспортёра. Префикс p1c_, который часто встречается в примерах, включается отдельной настройкой MetricNamePrefix; если вы её задали, а правило скопировали без префикса — правило просто никогда не сработает. Молча, разумеется.

Уровень 1: что снимать на сервере 1С и с какими порогами

Главный подозреваемый — диск (и на сервере 1С, и особенно на сервере СУБД). Пороги по времени отклика, устоявшиеся в 1С‑сообществе:

  • < 15 мс — хорошо;

  • 16–50 мс — требует внимания;

  • > 50 мс — надо что‑то делать; для SSD планка строже, там уже 25–30 мс означают проблему.

Плюс длина очереди к диску (ориентир — не больше числа устройств в массиве плюс 2) и % Disk Time выше 90% как признак упора.

По CPU, памяти и сети официальных «нормативов 1С» нет — берите общую инфраструктурную практику (устойчивая загрузка выше 80–85% долгое время, постоянный своп) и не выдавайте её за требование вендора.

Отдельно стоит помнить про механику памяти рабочих процессов: кластер сам контролирует объём памяти rphost по нескольким порогам. При превышении «временно допустимого» объёма на сервер перестают назначаться новые соединения; если превышение держится дольше заданного периода — процессы с наибольшим потреблением перезапускаются контролируемо; при достижении критического объёма — завершаются аварийно. Практический вывод: перезапуски rphost — это метрика, а не фон. Если вы видите просадку available_performance, синхронную с перезапуском rphost, вы нашли не две проблемы, а одну.

Техжурнал: когда метрик уже не хватает

Метрики отвечают «когда и насколько плохо». На «почему» отвечает технологический журнал.

Настраивается файлом logcfg.xml в каталоге conf платформы (/opt/1cv8/x86_64/current/conf/ на Linux, C:\Program Files\1cv8\conf\ на Windows). События, которые реально нужны для производительности:

  • TTIMEOUT — превышено время ожидания блокировки. Тот самый «Превышено максимальное время ожидания предоставления блокировки», таймаут по умолчанию 20 секунд;

  • TLOCK — операции с управляемыми блокировками;

  • TDEADLOCK — взаимоблокировки;

  • DBMSSQL / DBPOSTGRS — реальные запросы к СУБД с текстом и временем выполнения;

  • SDBL — запросы на внутреннем языке 1С;

  • CALL / SCALL — клиент‑серверные и межпроцессные вызовы;

  • EXCP — исключения со стеком;

  • MEM, LEAKS — память процессов и утечки по соединениям.

Классическая методика расследования «зависаний»: находим TTIMEOUT (жертва), идём назад к её TLOCK, ищем конфликтующий TLOCK по тем же ресурсам — это виновник, дальше по объекту метаданных.

Но включать это постоянно нельзя. Полный журнал без фильтров на нагруженной системе пишет столько, что сам становится источником тормозов; в сообществе разбирают кейсы журналов за сотню гигабайт. Рабочий компромисс:

xml

<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="/var/log/1c/logs" history="24">
    <!-- Постоянно: только дорогое и редкое -->
    <event><eq property="name" value="TTIMEOUT"/></event>
    <event><eq property="name" value="TDEADLOCK"/></event>
    <!-- Запросы к СУБД — только длиннее 3 секунд (duration в мкс) -->
    <event>
      <eq property="name" value="DBPOSTGRS"/>
      <ge property="duration" value="3000000"/>
    </event>
    <property name="all"/>
  </log>
</config>

history здесь — срок хранения архивных файлов в часах; ротация по времени, не по объёму, так что за размером раздела следите сами. И связка, которая работает лучше всего: метрики держим постоянно, полный ТЖ включаем на час по алерту — метрика говорит «в 14:20 просела производительность», журнал за этот час говорит, какой запрос и на каком объекте.

Четыре места, где мониторинг 1С молча ломается на Windows

Самое ценное из практики — не архитектура, а вот эти четыре штуки. Все они дают не ошибку, а тишину: агент установлен, служба запущена, данных нет.

1. Путь к rac.exe в YAML — только в одинарных кавычках. В двойных обратный слэш — escape‑последовательность, и C:\Program Files\1cv8\8.3.27.1000\bin\rac.exe разваливается на разборе ещё до старта экспортёра. На Linux этой проблемы нет вовсе, поэтому она приезжает сюрпризом.

2. Файл настроек, записанный PowerShell 5.1 с -Encoding utf8, получает BOM — а BOM в начале YAML ломает разбор. Пишите в ascii (и, соответственно, без кириллицы внутри), либо utf-8 без BOM.

3. Логи Windows не доезжают до хранилища — с кодом 200. Самая дорогая из четырёх. fluent‑bit с json_date_format iso8601 пишет таймзону без двоеточия (+0300), это не RFC3339 — и хранилище логов отвечает HTTP 200, а строку выбрасывает. Из всех форматов времени отвергался ровно этот: epoch, числа, отсутствие поля времени — проходило всё. Лечится одной строкой: json_date_format epoch.

Методологическая яма рядом: curl -d без явного Content-Type: application/json отправляет form‑urlencoded, и тело так же молча игнорируется с кодом 200. Час экспериментов по поиску причины оказался у меня невалидным именно из‑за этого. Проверяя приём логов руками — всегда указывайте Content‑Type явно.

Вторым слоем там же: у записей Windows Event Log нет поля уровня в привычном виде, а лог‑дашборд жёстко фильтрует по нему — то есть даже доехавшие записи были бы отрезаны. Нужен маппинг уровней Windows в syslog‑числа, единый со всеми остальными источниками.

4. Все Windows‑хосты сливаются в один пункт дашборда. windows_exporter скрапится локально, и instance у каждого хоста получается 127.0.0.1:9182. А типовые дашборды построены по instance целиком. Лечится relabel'ом на этапе сбора:

yaml

relabel_configs:
  - target_label: instance
    replacement: '<имя_хоста>'   # подставляется установщиком агента

Что алертить: минимальный набор

Если начинать с нуля, я бы взял такой набор — он покрывает большинство реальных обращений:

  1. rphost перезапустился — сам по себе и особенно синхронно с просадкой производительности.

  2. available_performance просела относительно собственного суточного уровня (не абсолютный порог!), for: 10m.

  3. TTIMEOUT/TDEADLOCK появились в журнале — на любом ненулевом количестве, это всегда конкретная боль конкретного пользователя.

  4. Клиентские лицензии подошли к лимиту — иначе про это узнаёте от пользователя, который не смог войти.

  5. Время отклика диска на сервере СУБД выше 20 мс устойчиво — раньше, чем это станет заметно в 1С.

  6. Регламентные задания идут в рабочие часы — кросс‑проверка времени запуска фоновых заданий с пиком пользовательской активности.

  7. Экспортёр 1С не отвечает (up{job="1c"} == 0) — иначе тишина в дашборде читается как «всё хорошо».

Итог

Снаружи кластера 1С доступно больше, чем принято думать: сеансы, лицензии, соединения, рабочие процессы, доступная производительность, регламентные задания, ресурсы серверов, техжурнал. Этого хватает, чтобы перевести спор «тормозит / не тормозит» в цифры и найти виновника в большинстве обращений — за час установки и без единого изменения в базе.

Чего снаружи не будет никогда — настоящего APDEX по бизнес‑операциям. Он живёт в замерах внутри прикладного кода, и путь к нему лежит через разговор с владельцем базы и согласованное целевое время T для каждой ключевой операции. Инструмент здесь — последняя проблема; первая — договориться, за сколько секунд документ должен проводиться.

И, пожалуй, главный практический вывод: в мониторинге 1С самые дорогие дефекты не кричат. Они выглядят как пустой дашборд, как HTTP 200 на выброшенной строке лога и как один пункт в списке хостов там, где их должно быть пять.


Если у вас уже настроен мониторинг 1С — проверьте прямо сейчас две вещи: что переменная дашборда не строится по метрике сеансов, и что в правилах алертов на available_performance есть фильтр по лейблу type. Это две минуты и два самых частых способа получить тихо неработающий мониторинг.

Комментарии (0)