Каждый системный администратор и разработчик 1С рано или поздно сталкивается с ситуацией, когда сервер приложений или сервер баз данных внезапно загружается под 100%. Пользователи начинают жаловаться на зависания, проведение документов длится минутами, а отчеты не формируются вовсе. При этом на сервере может работать несколько десятков пользователей, распределенных по разным информационным базам.
В этой статье мы подробно рассмотрим, как локализовать источник проблемы без радикального отключения баз данных и пользователей. Мы научимся определять виновника перегрузки — будь то конкретный пользователь, тяжелый фоновый процесс или неоптимальный запрос в коде 1С.
Прежде чем погружаться в инструменты 1С, нам необходимо понять общую картину распределения ресурсов. Для этого мы воспользуемся встроенными средствами операционной системы сервера.
Откроем Диспетчер задач (Task Manager) или, что более предпочтительно, Монитор ресурсов (Resource Monitor). Нам нужно определить, какой именно процесс потребляет ресурсы процессора (CPU) или дисковой подсистемы:
rphost.exe — проблема кроется на стороне сервера приложений 1С. Это означает, что выполняются тяжелые вычисления на встроенном языке 1С, происходит обработка больших массивов данных в памяти или запущены неоптимальные фоновые задания.sqlservr.exe для MS SQL Server или postgres.exe для PostgreSQL) — нагрузка вызвана тяжелыми запросами к базе данных.Рассмотрим обе ситуации подробнее и разберем алгоритмы действий для каждой из них.
Если сервер приложений 1С перегружен, мы можем быстро локализовать проблему с помощью стандартной консоли администрирования. Выясним, какой именно сеанс потребляет больше всего процессорного времени.
Откроем консоль администрирования серверов 1С, перейдем к нашему кластеру, выберем ветку «Информационные базы», зайдем в конкретную базу и найдем ветку «Сеансы» (в некоторых версиях платформы она называется «Сессии»). Если у вас настроено несколько баз, целесообразно анализировать общий список сеансов на уровне всего кластера в ветке «Сеансы».
В открывшейся таблице мы увидим список всех активных подключений. Платформа 1С предоставляет нам богатый набор метрик для каждого сеанса. Давайте разберем наиболее критичные показатели, на которые необходимо обратить внимание в первую очередь:
Отсортируем список сеансов по колонке «Процессорное время (текущее)» по убыванию. На первой строчке мы гарантированно увидим сеанс, который сильнее всего нагружает сервер приложений в данный момент. Обратите внимание на имя пользователя в колонке «Пользователь» и имя приложения в колонке «Приложение». Очень часто виновниками оказываются фоновые задания (приложение BackgroundJob) или регламентные операции.
Часто возникает ситуация, когда СУБД (например, MS SQL Server) загружена на 100%, но диспетчер задач показывает только общий процесс sqlservr.exe. Как понять, какой именно пользователь 1С запустил этот бесконечный или неоптимальный запрос? Для быстрого решения этой проблемы можно применить обработку для удобного анализа нагрузки на MS SQL Server из интерфейса 1С.
Для этого мы воспользуемся сопоставлением уникальных идентификаторов соединений. Разберем этот процесс по шагам:
SELECT
session_id AS SPID,
blocking_session_id AS BlockedBy,
cpu_time AS CPUTime,
reads AS Reads,
writes AS Writes,
status AS Status
FROM sys.dm_exec_requests;
CPUTime или Reads. Запомним значение в колонке SPID (идентификатор сессии в SQL).SPID из MS SQL Server.SPID из SQL с идентификатором соединения в 1С, мы мгновенно определим имя пользователя, его компьютер и конкретную информационную базу.После идентификации проблемного сеанса мы можем точечно завершить его прямо из консоли 1С, нажав на нем правой кнопкой мыши и выбрав команду «Удалить» (или завершить сеанс через свойства).
Что делать, если нагрузка кратковременная, но регулярная, и поймать ее вручную в консоли не получается? В этом случае нам на помощь приходит главный инструмент расследования инцидентов производительности — Технологический журнал (ТЖ). Для упрощения этой задачи можно использовать инструмент для автоматизации работы с технологическим журналом и поиска узких мест.
Мы можем настроить ТЖ так, чтобы он фиксировал только те запросы к СУБД, выполнение которых превышает определенный порог времени (например, более 3 секунд). Это позволит избежать создания терабайтных логов и не нагрузит рабочий сервер.
Для настройки ТЖ создадим файл конфигурации logcfg.xml в каталоге установки платформы (например, в папке C:\Program Files\1cv8\conf\) со следующим содержимым:
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\v8logs\HeavyQueries" history="24">
<event>
<eq property="Name" value="DBMSSQL"/>
<gt property="Dur" value="3000000"/>
</event>
<property name="all"/>
</log>
</config>
Разберем основные параметры этого файла:
location — директория, куда будут записываться логи. Убедитесь, что у пользователя, под которым запущен сервер 1С, есть права на запись в эту папку.history — время хранения логов в часах. В нашем примере старые логи будут автоматически удаляться через 24 часа.eq property="Name" value="DBMSSQL" — мы собираем события обращения к СУБД MS SQL Server (для PostgreSQL используйте значение DBPOSTGRS).gt property="Dur" value="3000000" — фильтрация по длительности запроса. Время указывается в микросекундах, то есть 3 000 000 мкс равняется 3 секундам.После активации технологического журнала в созданных файлах логов мы сможем найти подробную информацию по каждому долгому запросу. В логе будет содержаться:
p:processName);Usr);Если сервер уже "отпустило", но нам крайне важно выяснить, какой именно запрос уложил СУБД часом ранее, мы можем обратиться к кэшу планов запросов MS SQL Server. Нам помогут системные динамические представления (DMV).
Выполним следующий SQL-запрос в контексте нашей базы данных для получения ТОП-10 самых ресурсоемких запросов по времени процессора:
SELECT TOP 10
total_worker_time / execution_count AS [Average CPU Time],
execution_count AS [Execution Count],
total_worker_time AS [Total CPU Time],
SUBSTRING(st.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [SQL Text]
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
ORDER BY total_worker_time DESC;
Этот скрипт проанализирует статистику выполнения всех запросов в кэше и выведет их текст, отсортированный по суммарной нагрузке на CPU. Это поможет выявить скрытые проблемы, даже если пользователи уже вышли из системы.
Для эффективного контроля производительности сервера 1С рекомендуем придерживаться следующих правил:
Dur) более 5-10 секунд. Это практически не создаст нагрузки на сервер, но даст вам незаменимый инструмент для расследования инцидентов.