Подтвердить что ты не робот

ASP.NET Web Api 2/EF6 производительность инициализации первого вызова

Первый вызов нашего API всегда очень медленный. Например, ниже показано использование ЦП и время, необходимое для завершения первого вызова:

CPU usage

Первый вызов может занимать до 30 секунд и ест почти 100% процессор. Вызов 2 и 3 занимает 200 мс (как и должно быть). После повторного использования пула приложений он будет делать то же самое с первым вызовом.

Я немного читал об "разминке" IIS и делал следующее, но ничего не изменилось:

Инициализация приложений IIS 8:

IIS 8 Application Initialization

У меня есть следующий набор в IIS:

  • Установите Режим запуска на AlwaysRunning:

AlwaysRunning

  • Установите Тайм-аут перезаписи на 0:

Recycling Timeout

  • Установите Idle Time-out на 0:

Idle Time-out

  • Установите Preload Enabled на true на сайте:

Preload Enabled

Я фактически устанавливаю их в коде в RoleEntryPoint.OnStart().

using (var serverManager = new ServerManager())
{
    serverManager.ApplicationPoolDefaults.ProcessModel.IdleTimeout = TimeSpan.Zero;

    foreach (var application in serverManager.Sites.SelectMany(x => x.Applications))
    {
        application["preloadEnabled"] = true;

    }

    foreach (var applicationPool in serverManager.ApplicationPools)
    {
        applicationPool.AutoStart = true;
        applicationPool["startMode"] = "AlwaysRunning";
        applicationPool.ProcessModel.IdleTimeout = TimeSpan.Zero;
        applicationPool.Recycling.PeriodicRestart.Time = TimeSpan.Zero;

    }

    serverManager.CommitChanges();
}

Я почти уверен, что Entity Framework может быть виновником:

  • Мы создаем модели из примерно 100 таблиц в "дизайнере" модели EDMX.

  • Мы генерируем предварительно скомпилированные представления, созданные EF Power Tools.

  • В Application_Start() выполняется инициализация:

    using (var context = new MyContext())
    {
        context.Database.Initialize(false);
    }
    

У меня нет этих проблем с инициализацией при отладке.

Используется следующая технология:

  • .NET 4.5.1
  • ASP.NET Web Api 2
  • Entity Framework 6.1.1
  • IIS 8 (Azure Web Role)
  • Unity 3.5

Может ли кто-нибудь предоставить мне какие-либо другие идеи или предложения?

4b9b3361

Ответ 1

Не уверен, что кто-то еще обратился к этому, но я узнал о некоторых проблемах производительности, возникающих при первом запуске Entity Framework. Джулия Лерман рассказала об этом в своем курсе Pluralsight по платформе Entity Framework, о чем также говорится в следующей статье от Microsoft:

Одним из самых больших показателей производительности является время запуска, связанное с первым использованием контекста в прикладном процессе. Однако вы можете многое сделать, чтобы улучшить время запуска. Надеюсь, вы уже узнали эти трюки из своих собственных писем или других ресурсов, таких как документ MSDN по соображениям производительности на bit.ly/3D6AiC.

Шаг запуска, который часто препятствует повышению производительности, представляет собой создание представлений представлений отображения, где EF создает соответствующий SQL для запроса к каждому набору сущностей в модели. Эти взгляды становятся доступными, поскольку ваше приложение работает так, что для определенных запросов EF не должен работать над SQL на лету. Просмотр генерации происходит независимо от того, создана ли модель с помощью EF Designer или с кодом First. Вы можете предварительно сгенерировать эти представления и скомпилировать их в приложение, чтобы сэкономить время. http://msdn.microsoft.com/en-us/magazine/dn532202.aspx

Здесь, похоже, она не просто говорит о "начальной загрузке", а о фактическом первом использовании контекста. Я бы быстро поискал проблемы с Julie Lerman и Entity Framework. Я заметил подобную медлительность при первом вызове моего веб-API. Каждый вызов после первого был значительно быстрее. Я лично не счел это слишком ужасным, поэтому я игнорирую его (пока). Однако мне интересно, что это не происходит в режиме отладки. Извините, если вы уже изучили эти параметры, но я надеюсь, что это немного поможет.