«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)