Service Fabric Stateful Service в Azure - использование ОЗУ продолжает расти. Возможная утечка памяти - PullRequest
0 голосов
/ 10 мая 2019

Я запускаю приложение Service Fabric в кластере в Azure. Кластер имеет два набора шкал:

  • 4x узлы B2ms, в которых тип сервиса с состоянием размещен с Ограничениями размещения (первичный набор масштабов)
  • 2x F1-узла, где размещен тип сервиса без сохранения состояния.

В приложении есть два типа услуг

  • WebAPI - служба без сохранения состояния, используемая для получения статусов из системы через HTTP и отправки их в StatusConsumer.
  • StatusConsumer - служба с отслеживанием состояния, которая обрабатывает статусы и сохраняет последний. Экземпляр службы создается для каждой системы. Общается через RemotingV2.

Для своих тестов я использую Application Insights и Service Fabric Analytics для отслеживания производительности. Я соблюдаю следующие параметры:

Метрики для установленного масштаба: процент загрузки ЦП, операции чтения / записи диска / с

Applicaiton Insights: время отклика сервера - соответствует времени выполнения метода, который получает статусы в StatusConsumer с состоянием.

Service Fabric Analytics: счетчики производительности с агентом анализа журналов на узлах с отслеживанием состояния - используются для наблюдения за использованием ОЗУ узлами.

Каждая моделируемая система отправляет свой статус каждые 30 секунд.

В начале теста использование ОЗУ на каждом узле составляет около 40%, время отклика сервера Avg составляет около 15 мс, загрузка ЦП составляет около 10%, а операции чтения / записи менее 100 / с.

Сразу после начала теста использование ОЗУ начинает медленно нарастать, но в других наблюдаемых показателях нет никакой разницы.

Примерно через час моделирования 1000 систем использование оперативной памяти составляет около 90-95%, и проблемы начинают проявляться в других показателях - пики времени отклика сервера Avg со значениями примерно 5-10 секунд, а операции чтения / записи диска достигают примерно 500 / сек.

Это продолжается в течение 1-3 минут, затем использование оперативной памяти падает, и все возвращается в нормальное состояние. RAM Usage Server Response Time

На изображениях видно, что пик ОЗУ соответствует пику времени отклика сервера. В конце графика ОЗУ использование является плоским, чтобы показать, каково поведение без моделирования каких-либо систем.

Количество моделируемых систем только уменьшает или увеличивает время, необходимое ОЗУ для достижения критических уровней - в одном из тестов было смоделировано 200 систем, и рост использования ОЗУ был медленнее.

Что касается кода: в первых тестах код был более сложным, но чтобы найти причину проблемы, я начал удалять функциональность. Все еще не было никакого улучшения. Единственный раз, когда использование оперативной памяти не увеличивалось, это когда я комментировал весь код, а в теле метода, который получает статус, были только блок try / catch и return. В настоящее время код в StatusConsumer такой:

public async Task PostStatus(SystemStatusInfo status){
try{
    Stopwatch stopWatch = new Stopwatch();
    IReliableDictionary<string, SystemStatusInfo> statusDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, SystemStatusInfo>>("status");

    stopWatch.Start();

    using (ITransaction tx = this.StateManager.CreateTransaction())
    {
        await statusDictionary.AddOrUpdateAsync(tx,"lastConsumedStatus",(key) => { return status; },(key, oldvalue) => status);
        await tx.CommitAsync();
    }

    stopWatch.Stop();

    if (stopWatch.ElapsedMilliseconds / 1000 > 4) //seconds
    {
        Telemetry.TrackTrace($"Queue Status Duration: { stopWatch.ElapsedMilliseconds / 1000 } for {status.SystemId}", SeverityLevel.Critical);
    }
}
catch (Exception e) {Telemetry.TrackException(e);}
}

Как мне диагностировать и / или исправить это?

PS: после подключения к узлам с удаленным рабочим столом в Диспетчере задач я вижу, что при использовании ОЗУ около 85% «память» процесса SystemStatusConsumer, который «хранит» экземпляры микросервиса, не превышает 600 МБ. Это самый высокий уровень потребления, но он все еще не так высок - узел с 8 ГБ ОЗУ. Однако я не знаю, является ли это полезной информацией в этом случае.

...