ZDE, ZD, ZP Контроль нагрузки cсервера

Iv1

Client
Регистрация
21.02.2016
Сообщения
1 950
Благодарностей
774
Баллы
113
1. Зачем?
Когда делаешь шаблоны то, бывает, упираешься в то, что сервер «Не тянет». Т.е. он настолько загружен по ресурсам, что либо кубики сбоят, либо таймауты выходят, либо вообще видна ошибки уже начинает кидать.
На себе это почувствовал, когда на ZD с Memu работал и там прямо проблема работы более чем с 3-5-8 эмуляторами параллельно. Особенно когда создается новый экземпляр, который весит 2гига. И это надо создать, перекачать, запустить. А потом это еще умножить на X количество параллельных заданий. Комп начинал дымиться и сбоить.
А потом лови ошибки и думай это шаблон/приложение сбоит, или это чисто дело в ресурсах сервера.

2. Основный принцип.
Узких мест всего 3 у меня было:
- Нагрузка на процессор
- Свободное ОЗУ
- Загруженность дисковой системы (когда качаешь параллельно по 2гига, то она тоже сбоить может)

3. Теория.
Есть такое счастье как win API)) И счастье №2 что оно работает в продуктах зенки))
А так же такой класс как System.Diagnostics.PerformanceCounter

Если его дербанить, то можно найти множество параметров, которые контролировать можно.
Основная сложность – это выбрать «что именно», потому что там ДЕСЯТКИ – СОТНИ что можно контролировать.

Чтобы не упростить процесс разбора его – прикладываю уже готовый кубик, который выдает категонии что есть в винде и что можно дальше разбирать. Его код:

127944


Diagnostics - получение категорий:
System.Diagnostics.PerformanceCounter cpuCounter;
System.Diagnostics.PerformanceCounter ramCounter;
System.Diagnostics.PerformanceCounterCategory[] categories;

categories = System.Diagnostics.PerformanceCounterCategory.GetCategories();

//project.SendInfoToLog(categories[1].CategoryName);

    // Create and sort an array of category names.
    string[] categoryNames = new string[categories.Length];
    int objX;
    for(objX = 0; objX < categories.Length; objX++)
    {
        categoryNames[objX] = categories[objX].CategoryName;
    }
    Array.Sort(categoryNames);

    for(objX = 0; objX < categories.Length; objX++)
    {
        project.SendInfoToLog(categoryNames[objX]);
        objX++;
    }
Следующий шаг – это получение значений инстаносов. Т.е если для процессора, то контроль какого по счету? Или всех? Если для диска, то какого физического диска и как он вообще называется?

Код на пример получения названия дисков.
127945


Diagnostics - Получение PhysicalDisk (InstanceName):
   string categoryName = "PhysicalDisk";
    
    string machineName = "";
    System.Diagnostics.PerformanceCounterCategory pcc;
    string[] instances;

    pcc = new System.Diagnostics.PerformanceCounterCategory(categoryName);
    instances = pcc.GetInstanceNames();
    
    //If an empty array is returned, the category has a single instance.
    if (instances.Length==0)
    {
        project.SendInfoToLog("Пип");
    }
    else
    {
        // Otherwise, display the instances.
        project.SendInfoToLog("These instances exist in category \"{0}\" on " +
            (machineName.Length>0? "computer \"{1}\".": "this computer:") +
            pcc.CategoryName + pcc.MachineName);

        Array.Sort(instances);
        int objX;
        for(objX=0; objX<instances.Length; objX++)
        {
            project.SendInfoToLog(instances[objX]);
        }
    }
Единственная сложность – это иногда в системе выводит на русском, а указывать надо на английском. Есть люди и поумнее меня, которые расскажут почему так. Но я все нашел как правильно и выкладываю далее в шаблон.

Фактически свел весь контроль к 1 кубику, который если нагрузки нет – идет дальше, если нагрузка превышена – идет по красной на паузу и назад.

В самом кубике сразу задаются пороговые значение выше которых считается что большая нагрузка вот тут:

Задаем пороговые значение:
//    Задаем пороговые значение
float fCPULoadEdge = 70;
float fRAMLoadEdge = 2500;
float fSSDLoadEdge = 70;
Далее 2 раза! Снимаются данные по нагрузке, потому что бывают пиковые значения и колебания, которые портят картину. Потому 2 раза для надежности.

4. Самый главный кубик
127946

Контроль ресурсов - самый главный кубик:
//    Задаем пороговые значение
float fCPULoadEdge = 70;
float fRAMLoadEdge = 2500;
float fSSDLoadEdge = 70;

System.Diagnostics.PerformanceCounter ProcessorСounter;
System.Diagnostics.PerformanceCounter MemoryCounter;
System.Diagnostics.PerformanceCounter PhysicalDiskCounter;

ProcessorСounter = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", "_Total");
MemoryCounter = new System.Diagnostics.PerformanceCounter("Memory", "Available MBytes");
PhysicalDiskCounter = new System.Diagnostics.PerformanceCounter("PhysicalDisk", "% Disk Time", "0 D: E:");

var firstCall = ProcessorСounter.NextValue();
firstCall = PhysicalDiskCounter.NextValue();
Thread.Sleep(100);

    for (int i = 0; i < 2; i++)
    {
        Thread.Sleep(1000);
                
        float fValue = ProcessorСounter.NextValue();
        if (fValue > fCPULoadEdge) throw new Exception("Процессор перегружен \t" + fValue.ToString());
        project.SendInfoToLog(fValue.ToString() + "\t Processor \t % Processor Time");

        fValue = MemoryCounter.NextValue();
        if (fValue < fRAMLoadEdge) throw new Exception("Памяти мало \t" + fValue.ToString());
        project.SendInfoToLog(fValue.ToString() + "\t\t\t Memory \t Available MBytes");
        
        fValue = PhysicalDiskCounter.NextValue();
        if (fValue > fSSDLoadEdge) throw new Exception("SSD перегружен \t" + fValue.ToString());
        project.SendInfoToLog(fValue.ToString() + "\t\t\t PhysicalDisk \t % Disk Time \t 0 D: E:");

        project.SendInfoToLog("\n");
        
    }
Названия дисков подставить конечно же свои!!!
В проект приложил кубик где можно взять называние:

Шаблон приложил.

p.s. Все - буду благодарен за признание и надеюсь это поможет делать высоконагруженные проекты.
 

Вложения

zarufakis

Client
Регистрация
22.03.2019
Сообщения
1 743
Благодарностей
1 137
Баллы
113
Не совсем понятно, как соотносятся эти значения

128799
 
  • Спасибо
Реакции: cooki

Iv1

Client
Регистрация
21.02.2016
Сообщения
1 950
Благодарностей
774
Баллы
113
Не совсем понятно, как соотносятся эти значения

Посмотреть вложение 128799

Возможно потому что диспетчер усредняет за секунду (или сколько там в настройках), а через API ловит "моментальное" значение, которое прыгает прямо существенно.
Потому в кубике 2 раз чекаются значения, чтобы исключать моменты "когда внезапно изменилось в моменте"
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)