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

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

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

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

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

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

Спасибо вам заблаговременно!

4b9b3361

Ответ 1

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

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

Он, вероятно, второй, поскольку по умолчанию используется 20 минут, первый по умолчанию - 29 часов, я считаю.

Ответ 2

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

Ох и его бесплатно для до 50 сайтов!

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

TL; д-р

После довольно обширного тестирования и сбора релевантных источников, чтобы попытаться решить проблему, я думаю, что минимальное решение может быть (не проверено), чтобы добавить этот код в 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 возникает при переключении пула приложений в режим ожидания).

Как это работает (если это так):

  • В настройках пула приложений 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 или not и может меняться со временем.

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

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