воскресенье, 20 октября 2019 г.

Выявление повышенной загрузки процессора на сервере 1С - случай №1


Дано:
Сервер 1С: Wndows Server 2016 Standard, 32 Гб ОЗУ, 12 ядерный процессор 2.7 ГГц; платформа 1С 8.3.15.1565 с настройками по умолчанию; 60 баз, лицензия платформы ПРОФ.
Процессор загружен постоянно на 85-100% (и каждое ядро, и суммарно).
Требуется выявить причину такой загрузки и разгрузить процессор.

Решение:

Сначала самое простое - откроем диспетчер задач Windows, закладку "Details" и отсортируем список процессов по колонке "CPU". Видим один или несколько процессов rphost.exe в топе - значит, процессор загружает 1С.
Если процессор загружен, это означает, что какие-то задачи выполняются. А так как процессор загружен слишком часто, это означает, что все это время задачи выполняются, а значит они либо долго выполняются, либо быстро и часто выполняются. Но что именно выполняется суммарно долго в 1С?

Находим топ суммарно длительных серверных вызовов.

Настраиваем сбор ТЖ
<?xml version="1.0"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\logs1c" history="2">
<event>
<eq property="name" value="CALL"/>
</event>
<event>
<eq property="name" value="SCALL"/>
</event>
<property name="all"/>
</log>
</config>

Для парсинга собранного ТЖ пишем скрипт:
# Топ суммарно длительных вызовов
# Суммарная длительность :: База :: Вызов
y=0;
#grep -P ',CALL,' ./rphost*/*.log | head -n 10000 | awk '{
grep -P ',CALL,' ./rphost*/*.log | awk '{
posDlit = match($0, "-");
posCALL = match($0, ",CALL");
LenDlit = posCALL - posDlit;
dlit = substr($0, posDlit+1, LenDlit); #длительность вызова (для 8.2 1/10000 секунд, для 8.3 1/1000000 секунд)

ToAdd = 0; # определяет, выполнять ли проверку в массиве и добавление, т.е. пропускать строку или нет

posFunc = match($0, ",Func=");
if(posFunc!=0) # у регламентных заданий так
{
ToAdd = 1;
posBase = match($0, "p:processName=");
LenBase = posFunc - posBase;
pBase = substr($0, posBase, LenBase);
gsub("p:processName", "Base", pBase);
posMemory = match($0, ",Memory=");
LenMethod = posMemory - posFunc;
Method = substr($0, posFunc+1, LenMethod);
KeyStr = pBase " :: " Method;
}
if(posFunc==0) # у пользовательских вызовов так
{
posContext = match($0, ",Context=");
if(posContext!=0)
{
ToAdd = 1;
posBase = match($0, "p:processName=");
postClientID = match($0, ",t:clientID=");
LenBase = postClientID - posBase;
pBase = substr($0, posBase, LenBase);
gsub("p:processName", "Base", pBase);
strContexMore = substr($0, posContext+1);
posEndContext = match(strContexMore, ",");
Context = substr(strContexMore, 1, posEndContext);
KeyStr = pBase " :: " Context;
}
}

if(ToAdd==1)
{
# определяем есть ли уже этот контекст в массиве
isexist = 0;
for(i in arr)
{
# если есть, то прибавляем только длительность
if(arr[i]==KeyStr) {brr[i]+=dlit; isexist = 1; break;}
}
if (isexist == 0) # если отсутствует, то добавляем новый элемент массива
{
y+=1;
arr[y] = KeyStr;
brr[y] = dlit;
}
}
} END {
for (i in arr) {print brr[i] " :: " brr[i]/1000000 " sec :: " (brr[i]/1000000)/60 " min :: " arr[i]}
}' | sort -rnb | head -n 30


С помощью GitBash в директории ТЖ запускаем скрипт, получаем результат:

В топе оказались регламентные задания. Заходим в базы и проверяем периодичность каждого регламентного задания.

Периодичность высокая. 
Далее для разгрузки процессора есть следующие решения.
 1) Если есть период нерабочего времени, то переносим время запуска именно в нерабочее время. Если нерабочего времени нет (всегда рабочее), то уточняем следующий пункт.  
 2) Уточняем, пользуются ли пользователи полнотекстовым поиском; если нет, то отключаем регламентные задания; если да, то уточняем допустимый предел актуальности данных (например, на вчерашний день, 2-часовая актуальность) и меняем периодичность запуска соответственно. Проблему данный пункт не решает, если пользователь отвечает, что порога актуальности быть не должно или он должен быть слишком мал, как в примере. Тогда уточняем пункт (3). 
3)  Возможно, полнотекстовый поиск требуется выполнять только по определенным таблицам, полям, тогда для остальных полей требуется отключить свойство использования полнотекстового поиска.
4) И самый сложный случай, когда полнотекстовый поиск требуется для всех полей, часто меняются данные. Требуется либо увеличение количества ядер (и желательно их частоты), либо перенос сервиса полнотекстового поиска на отдельный сервер. 






Комментариев нет:

Отправить комментарий