ASP.NET MVC: сначала доступ через несколько минут замедляется, затем быстро выполняется каждый следующий запрос - PullRequest
24 голосов
/ 30 июля 2010

при первом доступе к любой странице моего веб-сайта ASP.NET MVC этот первый запрос выполняется медленно. Требуется около 4-5 секунд для загрузки. Но каждый следующий запрос к любой странице выполняется быстро.

Когда я жду несколько минут или час, тогда каждый первый запрос снова замедляется. Каждый следующий запрос выполняется быстро.

Я думаю, что IIS 7 компилирует код и хранит его в памяти. Через некоторое время он удалит его из памяти, поэтому он должен скомпилировать его снова.

Что я могу сделать, чтобы каждый первый запрос выполнялся так же быстро, как и каждый следующий? (Без предварительной компиляции моего источника, если это возможно)

Заранее большое спасибо!

Ответы [ 5 ]

21 голосов
/ 30 июля 2010

Если это рабочий сервер, то почему бы не попробовать добавить монитор веб-сайта; такие как время работы робота . Он в основном запрашивает заголовки ваших сайтов и каждые 5 минут получает коды состояния, такие как «200-ok», «404-not found» и т. Д. Таким образом, ваш сайт всегда раскручивается и не влияет на файлы журнала / аналитику, так как запрашиваются только заголовки. Я использую это для своих облачных сайтов, так как считаю, что для их раскрутки требуется 5 секунд, что влияет на загрузку сайта. С монитором они мгновенные.

Да, и это бесплатно для до 50 сайтов!

17 голосов
/ 30 июля 2010

Это может быть параметр перезапуска рабочих процессов в пуле приложений, проверьте его значение и либо отключите, либо увеличьте его.

Может также быть рабочим процессом Завершение работы после простоя из-за низкой производительности для пула приложений.

Вероятно, это второе, поскольку по умолчанию это 20 минут, первое по умолчанию - 29 часов.

5 голосов
/ 06 июля 2013

Это почти наверняка параметр ожидания простоя пула приложений (а не перекомпиляция кода).

Время ожидания простоя пула приложений в IIS по умолчанию составляет 20 минут.Это означает, что если по прошествии 20 минут к вашему приложению не поступит никаких запросов, IIS остановит рабочий процесс для пула приложений , и приложение снова станет «холодным».Кто бы ни сделал следующий запрос, он подождет несколько секунд, пока IIS перезапустит рабочий процесс и «прогреет» ваше приложение.

Если вы не хотите, чтобы IIS автоматически «охладил» ваше приложение после определенного периода времени.неактивность, вы можете отключить тайм-аут простоя пула приложений, установив его в 0.

1 голос
/ 30 июля 2010

Если у вас есть постоянный поток посетителей, это не должно быть проблемой на производстве. Кроме того, если вы физически не изменяете какой-либо из своих исходных файлов, IIS не будет перекомпилировать его, когда оно раскручивает ваше приложение.

Кроме того, взгляните на доступные параметры компиляции .NET: http://technet.microsoft.com/en-us/library/cc725812(WS.10).aspx

0 голосов
/ 17 ноября 2016

ТЛ; др

После довольно обширного тестирования и сбора соответствующих источников, чтобы попытаться решить проблему, я думаю, что минимальное решение может быть (не проверено), чтобы добавить этот код в global.asax:

    protected void Application_End()
    {
        ...
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://web_domain.tld");
        using (HttpWebResponse response = (HttpWebResponse)
            request.GetResponse())
        {
        }
        ...
    }

Во время написания поста это использовалось для эффективного поддержания сайта, над которым я работал, «всегда активным» - с соединением установки Idle Time-out (minutes) в IIS в 0, как упоминалось в других ответах. Однако я думаю, что изменение Idle Time-out (minutes) может не потребоваться (при условии, что событие Application_end возникает, когда происходит переключение пула приложений в режим ожидания).

Как это работает (при условии, что это работает):

  1. В настройках пула приложений IIS есть 2 параметра, которые влияют на приостановку или завершение работы приложения. Один из них - Idle Time-out (minutes), который по умолчанию равен 20 минутам, и когда указанное время истекает с момента последнего запроса , рабочий процесс приостанавливается или завершается. Когда приходит следующий запрос, рабочий процесс возобновляется или запускается снова, и возникает событие Application_start (и поэтому, если обработчик Application_start определен в global.asax, он выполняется). В случае проекта, над которым я работал, запуск Application_start занял около 17 секунд. Таким образом, если сайт был «оставлен в покое» в течение 21 минуты, а затем пришел новый запрос, то для отправки ответа потребовалось чуть более 17 секунд (Application_start + обработка страницы). Когда в течение 20 минут был отправлен другой запрос, ответ был отправлен значительно быстрее (возможно, менее 1 с), поскольку Application_start уже обработан.

Установка значения Idle Time-out (minutes) в 0 приводит к тому, что рабочий процесс никогда не приостанавливается / не прекращается (по крайней мере, из-за простоя - может быть другая причина, описанная ниже).

  1. Помимо Idle Time-out (minutes), в разделе Recycling дополнительных настроек IIS есть также настройка Regular time interval (minutes). По умолчанию это 1740 минут (29 часов) и является обычной запланированной задачей, из-за которой пул приложений периодически перезагружается (период является фиксированным). Я понял, что это предотвращает накопление возможных утечек памяти, которые, если они есть, могут в конечном итоге привести к сбою сервера из-за перегрузки всей памяти. Эффект утилизации пула приложений заключается в том, что возникает событие Application_end. Однако после завершения приложения оно не запускается автоматически, поэтому событие Application_start не вызывается до тех пор, пока не поступит фактический запрос (что аналогично первому случаю). Таким образом, в случае вышеупомянутого веб-приложения, над которым я работал, снова потребовалось бы около 17 секунд для обработки первого запроса, поступившего после того, как произошла переработка. Изменение этого значения на 0 отключает рециркуляцию, но я полагаю, что не стоит полностью отключать рециркуляцию из-за возможности накопления утечек памяти с течением времени (что может быть даже вызвано ошибками в сторонних библиотеках). Я понимаю, что мнения расходятся относительно того, следует ли установить это значение на 0 или , а не и может со временем меняться.

Возможное решение (без изменения настроек IIS): Если запросы отправляются достаточно часто, пул приложений может никогда не переключиться в режим ожидания. В случае повторного использования это также может привести к повторному запуску приложения. Это может быть достигнуто, например, с помощью стороннего сервиса, как описано в @ Rippo.

Предлагаемое решение: Было замечено, что пул приложений recycling вызвал событие Application_end. Предполагая, что он также поднимается при переключении пула приложений в Режим ожидания , может показаться достаточным создать запрос в обработчике событий Application_end на веб-сайт, который в обоих случаях вызовет приложение, чтобы начать снова (вызывает событие Application_start). Код вверху ответа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...