Кто уложил 1С, или мониторинг загрузки кластера в разрезе пользователей с помощью Grafana





Мониторингом различных параметров работы кластера 1С в zabbix сейчас уже никого не удивишь. Собственно потребление памяти, процов и места на серверах обычно настраивают первыми. Потом идет мониторинг в разрезе rphost’ов и различные метрики функционирования SQL сервера. Но вот когда уже все это есть, то временами возникает вопрос — какой же конкретно нехороший человек пытается съесть все (ну не все, но много) ресурсы сервера?

Можно смотреть в консоль кластера и ловить редиску там. Можно анализировать журнал регистраций, включать технологический журнал или накапливать статистку в специализированных базах 1С. Но, «настоящим» сисадминам проще как-то с внешними скриптами, базами данных и, например, Grafana. Расскажу что у нас получилось.

Для начала надо понимать, что задача возникла не на ровном месте. Время от времени rphost росли до 20-30GB, или обнаруживались зависшие сессии в сутки, а то и более. "Проблемых" пользователей ловили через консоль, но помогало это относительно — пользователи через день уже не помнили что запустили, поиск по журналу за сутки занимал много времени и не всегда заканчивался успехом, в общем процесс надо было как-то ввести в управляемое русло.

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

Статья — не полноценная инструкция по разворачиванию системы (и так получилась какая-то огромная для меня). Скорее описан подход к решению проблемы. И вопрос оптимизации этого подхода для меня скорее открыт, чем решен 🙂

Структура решения вкратце

  1. "1C Remote Administation Client" (RAC) подключается к "1C Remote Administation Server" (RAS) и получает информацию о кластере 1С.
  2. Скрипт в Powershell запускает RAC, структурирует полученную от него информацию, и посылает ее в базу MySQL.
  3. В базе MySQL к полученным записям добавляется время получения этих записей.
  4. Grafana с помощью специфических запросов в MySQL визуализирует данные о кластере 1С.
  5. Использую Notification channels из Grafana рассылаем уведомления о проблемах заинтересованным лицам.

Как ставить и запускать службу RAC/MySQL/Grafana рассказывать не буду — информации достаточно.

Создаем базу MySQL для хранения данных:

CREATE DATABASE 1c_monitoring;
ALTER DATABASE 1c_monitoring CHARACTER SET utf8 COLLATE utf8_general_ci;

Создаем таблицу сессий

use 1c_monitoring
create table sessions(
id serial primary key,
server varchar(255) NOT NULL,
clock timestamp,
uuid varchar(36) NOT NULL,
base varchar(255),
user varchar(255) ,
type varchar(255) NOT NULL,
started timestamp,
last timestamp,
sleep bool default false,
current BIGINT,
5min BIGINT,
total BIGINT,
duration_cur bigint(20),
duration_db_cur bigint(20)
);

Что бы работали запросы Grafana в базу MySQL необходимо убрать режим "ONLY_FULL_GROUP_BY", для этого нужно указать все необходимые (те что уже есть) режимы исключив "ONLY_FULL_GROUP_BY"

SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

Рекомендуется сделать специального пользователя MySQL для удаленных подключений к базе 1c_monitoring (у меня adm1c)

В Grafana через web-интерфейс прописываем созданную БД как Data Sources:

Name MySQL 1C
MySQL Connection  
Host mysql:3306
Database 1c_monitoring
User adm1c
Password Ну понятно

На сервер с кластером 1С ставим mysql-connector-net и подключаем PowerShell скрипт, который раз в 5 минут считывает для каждой активной сессии имя пользователя, Память(текущая),Память(5 минут), Память(Всего) и время старта сессии и вставляет из в БД (скриптик приложен — как-то страшно его показывать, т.к. выглядит… не идеально)

Данные в БД мы получили — приступаем к визуализации. Добавляем в Grafana dashboard, в него panel, в разделе metrics вводим запрос к графане (синтаксис там SQL-подобный с использованием специальных агрегатных функций Grafana, которые начинаются с "__"):

SELECT
$__timeGroupAlias(clock,5m,0),
concat(user,' (',base,')') AS metric,
max(Current) AS "memory"
FROM sessions
WHERE
$__timeFilter(clock) and
server = 'SRV-BASE'
GROUP BY 1,2
ORDER BY $__timeGroup(clock,5m,0)

Ну и после некоторого кряхтенья получаем график использования памяти в разрезе пользователей:

Потребление памяти по пользователям

Подобным же образом визуализировали время сессий.

Продолжительность сессий пользователей

Ну как бы здорово — видим кто ест всю память, у кого сессии зависли (по факту скорее фоновые задания, запущенные во время работы), для регламентов видим какие регламенты вдруг стали выполняться сильно дольше. Но оперативности, к сожалению, нет. Если никто не посмотрит на dashboard (а туда начинают смотреть когда пользователи начинают жаловаться), то никто и не дернется. Зато получили профили использования ресурсов и можно реагировать, если что-то идет не так.

Сначала сделали оповещение группы 1С по почте используя стандартный функционал Grafana рассылки уведомлений через электронную почту. Для этого надо сконфигурить Notification channels для работы с почтовым сервером, а потом настроить Alert Rules. Как-то вот так:

Настройка Alert Rules

Теперь группе поддержки 1С стало сложнее пропустить предупреждение. Но если мы предупреждаем "одинэсников", то почему не сообщить сразу пользователю, что он каким-то образом запустил некую ресурсоемкую задачу? Если пользователь сразу отреагирует, то и группе поддержки 1С будет проще. В каких-то ситуациях можно не реагировать (все знают что запущена тяжелая обработка — "бобёр выдыхай"), в каких-то надо срочно прерывать задачу, в каких-то надо ставить на рефакторинг функционал и сразу понятно кто будет бизнес-заказчиком этого рефакторинга.

Вишенка на торте — используем webhook в Grafana (через все тот же Notification channels)! Grafana при включенном алерте посылает json с описанием проблемы на webhook сервер. Сервер берет из json пользователя, сервер, базу и время или размер сессии, шлет это все в bash-скрипт, который сопоставляет имя пользователя и его почту используя внутрикорпоративный портал, формирует сообщение и посылается на почту пользователю.

Пользователь получает что-то вроде:

Добрый день, <Имя пользователя>, согласно данным системы мониторинга 1С сегодня (17.06.2024) в 20:01 наблюдалось аномальное потребление Вами ресурсов сервера 1С SRV-BASE  в информационной базе un_acc30 — 1095.84 MB. Большая просьба максимально детализовано сообщить какие операции в 1С в это время вы совершали и было ли что-то необычное (тормоза, вылет) во время работы. Информацию просьба направлять на ITSupport.

 

У нас поставлены 2 хука на превышение памяти на сессию больше 1GB и на продолжительность сессии более суток. Скрипты написаны на bash и если будут кому интересны приложу. Выглядят тоже ужасно + наша специфика с определением e-mail (пользователи создаются с русским ФИО в качестве username и за их e-mail’ами приходится дополнительно лазить на внутрикорпоративный портал).

Ну собственно всё. 3 месяца ушло на то, чтобы убедить пользователей не пугаться и сразу сообщать что было запущено и что с этим сделать.

В результате отловили ошибки в фоновых заданиях на формирование печатных форм (которые висли), оптимизировали пачку регламентов (которые работали часами), научили пользователей использовать более легкие отчеты вместо монстроидальных и отучили запускать тяжелые отчеты с большим периодом и широкой выборкой.

Теперь вот надо определить следующее узкое место, которое можно замониторить через Grafana…

UPD. 26/09/2024 Уважаемый @klimov_andrey, как автор упомянутых скриптов, модифицировал скрипт загрузки данных в Grafana. Теперь скрипт

  • проверяет запущены ли RAS и 1С агент
  • проверяет совпадают ли версии 1С агента и RAS и, в случае если они отличаются, устанавливает RAS нужной версии.
  • В 8.3.15 изменился формат вывода данных из-за чего старый скрипт не грузил данные. Исправлено.
  • Шлет на почту сообщения об ошибках

 

24 Comments

  1. blackhole321

    Если не секрет, почему в качестве СУБД использовали MySQL, а не MSSQL или Postgres?

    Reply
  2. DonAlPatino

    (1) Как говориться «так исторически сложилось». Первоначально пытались решить задачу используя zabbix, который уже работал на mysql. Поэтому данные туда и грузили. Ну дальше все так и осталось. Пока запускали я наконец-то понял смысл Time-Series Databases вообще и почему так пиарят тот же Prometeus в частности. Но пока решили не переделывать — данных не много

    Reply
  3. blackhole321

    (2)

    ески сложилось». Первоначально пытались решить задачу используя zabbix, который уже работал на mysql. Поэтому данные туда и грузили. Ну дальше все так и осталось. Пока запускали я наконец-то понял смысл Time-Series Databases вообще и почему так пиарят тот же Prometeus в частности. Но пока решили не переделывать — д

    Спасибо!

    Reply
  4. theelectric

    Вячеслав, подскажите, пжл, в чем может быть ошибка соединения? Первая часть кода скрипта полностью как у Вас…

    .
    ac.exe : Ошибка соединения с сервером

    C:Users1sDesktopLoad2MsSqlnew.ps1:8 знак:12

    + $cluster = .
    ac.exe cluster list | % {if ($_ -match ‘cluster’){$_ -replace «#k8SjZc9Dxk.* …

    + ~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo : NotSpecified: (Ошибка соединения с сервером:String) [], RemoteException

    + FullyQualifiedErrorId : NativeCommandError

    Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение

    .
    ac.exe : Ошибка разбора параметра: cluster

    C:Users1sDesktopLoad2MsSqlnew.ps1:9 знак:17

    + $racInfobases = .
    ac.exe infobase —cluster=$cluster summary list

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo : NotSpecified: (Ошибка разбора параметра: cluster:String) [], RemoteException

    + FullyQualifiedErrorId : NativeCommandError

    .
    ac.exe : Ошибка разбора параметра: cluster

    C:Users1sDesktopLoad2MsSqlnew.ps1:34 знак:16

    + $racSessions = .
    ac.exe session —cluster=$cluster list

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo : NotSpecified: (Ошибка разбора параметра: cluster:String) [], RemoteException

    + FullyQualifiedErrorId : NativeCommandError

    Reply
  5. theelectric

    (4) Даже напрямую обращаясь к кластеру выходит ошибка соединения. Подскажите, в чем может быть проблема?

    Reply
  6. theelectric

    (5) И даже так не соединяет:

    Reply
  7. DonAlPatino

    (6)Служба RAS соответствующей версии 1С установлена?

    Reply
  8. theelectric

    (7) Да, аналогичной версии

    Reply
  9. DonAlPatino

    (8)Администраторы кластера не созданы?

    Reply
  10. theelectric

    (9) Нет, не созданы

    Reply
  11. DonAlPatino

    Ну в общем вот это «rac cluster list» должно отрабатывать на самом сервере с запущенной службой RAS. и отдавать id кластера.

    У меня на 5 серверах отрабатывает без всякого шаманства.

    Я бы попробовал переставить все нуля на пустой машине. Вот PS скрипт для установки RAS

    $version = Get-ChildItem «C:Program Files1cv8» | ? {$_.Name -like ‘*.*.*.*’} | select -Expand Name | %{[Version]$_} | sort | select -last 1 | %{[string]$_}

    Set-Location «C:WindowsSystem32»

    .sc stop ras

    .sc delete ras

    .sc create ras binpath= «C:Program Files1cv8$versionin
    as.exe cluster —service» displayname= «1C:Enterprise 8.3 RAS» start= auto

    .sc start ras

    Reply
  12. theelectric

    (11) Оказывается, ras не был запущен. Спасибо большое за помощь!

    Reply
  13. theelectric

    Вячеслав, у Вас опыт работы с Grafana уже есть… А подскажите, в чем может быть проблема данной ошибки, как указано на рисунке ниже?

    Reply
  14. ImHunter

    Тоже сделал подобный мониторинг — Дженкинсом периодически запускается os-скрипт (допиленная Считалка сеансов), он выгружает в Elastic, результаты смотрим в Kibana.

    Reply
  15. DonAlPatino

    (14) А почему именно Дженкинсом? Я вот вижу в статьях, что время от времени люди используют его как запускатор скриптов… А вот в чем тут профит не пойму…

    Reply
  16. ImHunter

    (15) Ну так сбор нагрузки — это срез данных на

    текущий момент времени. Для истории нагрузки, соответственно, нужно периодически собирать данные. Этим и занимается Дженкинс — постоянно запускает скрипт.

    Reply
  17. DonAlPatino

    (16) А у меня просто по шедулеру стартует этот самый сбор статистики. В чем преимущество использования именно Дженкиса? Не холивара ради — может я какую-то киллфичу пропускаю по причине того, что дженкинс не знаю вообще. Это же CI/CD в первую очередь? Или я сильно ошибаюсь?

    Reply
  18. DonAlPatino

    (13)

    Что-то я не вижу на скрине ‘AS’ вообще. Это этот запрос?

    SELECT

    $__timeGroupAlias(clock,5m,0),

    concat(user,’ (‘,base,’)’) AS metric,

    max(Current) AS «memory»

    FROM sessions

    WHERE

    $__timeFilter(clock) and

    server = ‘SRV-BASE’

    GROUP BY 1,2

    ORDER BY $__timeGroup(clock,5m,0)

    Ну для начала посомтрте в «generated sql». Я так понимаю у вас не mysql, а mssql?

    Reply
  19. theelectric

    Да, мы переработали Ваш скрипт для сохранения данных по сеансам в MS SQL. Вот что нам выдает ваш запрос в Grafana:

    Reply
  20. ImHunter

    (17) Ну хз. У нас — для однообразия. Чтобы понятно было — что, когда и чем запускается.

    Reply
  21. DonAlPatino

    (19) ну там же русским языком написано, что ему не нравится. Надо погружаться в T-SQL. Графана тут совсем не при делах…

    Reply
  22. DonAlPatino

    (20)Я правильно понимаю что вы используете Дженкис как централизованную систему управления запуском скриптов на куче серверов? Я как-то не рассматривал его в таком контексте

    Reply
  23. theelectric

    Я понял, буду копать в эту сторону. Спасибо!

    Reply
  24. ImHunter

    (22) Да, так

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *