Arreglando la carga inicial lenta para IIS

129

IIS tiene una característica molesta para los sitios web de bajo tráfico donde recicla los procesos de los trabajadores no utilizados, lo que hace que el primer usuario en el sitio después de un tiempo obtenga un retraso extremadamente largo (más de 30 segundos).

He estado buscando una solución al problema y he encontrado estas posibles soluciones.

A. Use el complemento de inicialización de la aplicación

B. Use Auto-Start con .NET 4

C. Deshabilite el tiempo de inactividad (en Restablecimiento de IIS)

D. Precompilar el sitio

Me pregunto cuál de estos es el preferido y, lo que es más importante, ¿por qué hay tantas soluciones al mismo problema? (Supongo que no lo son, y simplemente no entiendo algo correctamente).

Editar

Realizar C parece ser suficiente para mantener mi sitio caliente, pero descubrí que la raíz real de la lentitud de mi sitio tiene que ver con Entity Framework, que parece que no puedo entender por qué se está enfriando. ¡Vea esta pregunta, que desafortunadamente no ha sido respondida todavía ha sido respondida!

Eventualmente solo tuve que hacer un script de calentamiento para visitar mi sitio ocasionalmente para asegurarme de que se mantuviera rápido.

Cavyn VonDeylen
fuente
Hola amigo, ¿es suficiente realizar C? Por qué ? ¿Solo necesitamos usarlo o también debemos deshabilitar el reciclado? Siempre siento que el segundo día la primera solicitud es muy lenta de IIS7.5
qakmak

Respuestas:

36

Las opciones A, B y D parecen estar en la misma categoría, ya que solo influyen en la hora de inicio inicial, hacen un calentamiento del sitio web como la compilación y carga de bibliotecas en la memoria.

Usar C, establecer el tiempo de espera inactivo, debería ser suficiente para que las solicitudes posteriores al servidor se atiendan rápidamente (reiniciar el grupo de aplicaciones lleva bastante tiempo, en el orden de segundos).

Hasta donde sé, el tiempo de espera existe para ahorrar memoria que otros sitios web que se ejecutan en paralelo en esa máquina podrían necesitar. El precio es ese tiempo de carga lento.

Además del hecho de que el grupo de aplicaciones se cierra en caso de inactividad del usuario, el grupo de aplicaciones también se reciclará por defecto cada 1740 minutos (29 horas).

De technet:

Los grupos de aplicaciones de Internet Information Services (IIS) se pueden reciclar periódicamente para evitar estados inestables que pueden provocar bloqueos, bloqueos o pérdidas de memoria en la aplicación.

Mientras el reciclaje del grupo de aplicaciones esté activado, debería ser suficiente. Pero si realmente desea un rendimiento de primer nivel para la mayoría de los componentes, también debe usar algo como el Módulo de inicialización de aplicaciones que mencionó.

Răzvan Flavius ​​Panda
fuente
Entonces, ¿recomendaría simplemente deshabilitar el tiempo de inactividad? ¿Causaría problemas a lo largo de la línea (supongo que está ahí por alguna razón)?
Cavyn VonDeylen
3
En realidad, esto no soluciona mi problema (vea mi edición), pero acepté ya que respondió mi pregunta original.
Cavyn VonDeylen
10

Desafío de alojamiento web

Debe recordar que ninguna de las opciones de configuración de la máquina está disponible si está alojado en un servidor compartido, como lo están muchos de nosotros (compañías más pequeñas e individuos).

ASP.NET MVC Overhead

Mi sitio tarda al menos 30 segundos cuando no ha sido golpeado en más de 20 minutos (y la aplicación web se ha detenido). Es terrible.

Otra forma de probar el rendimiento

Hay otra forma de probar si es el inicio de ASP.NET MVC u otra cosa. Coloque una página HTML normal en su sitio donde pueda acceder directamente.
Si el problema está relacionado con el inicio de ASP.NET MVC, la página HTML se reproducirá casi de inmediato incluso cuando la aplicación web no se haya iniciado.
Así fue como reconocí por primera vez que el problema estaba en el inicio de ASP.NET MVC. Cargué una página HTML en cualquier momento y se cargaría muy rápido. Luego, después de presionar esa página HTML, presioné una de mis URL ASP.NET MVC y recibí el mensaje de Chrome "Esperando raddev.us ..."

Otra prueba con script útil

Después de eso, escribí un script LINQPad (consulte http://linqpad.net para obtener más información) que llegaría a mi sitio web cada 8 minutos (menos del tiempo para que se descargue la aplicación, que debería ser de 20 minutos) y dejé Funcionó durante horas.

Mientras se ejecutaba la secuencia de comandos, llegué a mi sitio web y cada vez que mi sitio apareció increíblemente rápido. Esto me da una buena idea de que lo más probable es que la lentitud que estaba experimentando se debiera a los tiempos de inicio de ASP.NET MVC.

Obtenga LinqPad y puede ejecutar el siguiente script: simplemente cambie la URL a la suya y déjela ejecutar, y puede probar esto fácilmente. Buena suerte.

NOTA : En LinqPad, deberá presionar F4 y agregar una referencia a System.Net para agregar la biblioteca que recuperará su página.

TAMBIÉN : asegúrese de cambiar la variable URL de cadena para apuntar a una URL que cargará una ruta desde su sitio ASP.NET MVC para que el motor se ejecute.

System.Timers.Timer webKeepAlive = new System.Timers.Timer();
Int64 counter = 0;
void Main()
{
    webKeepAlive.Interval = 5000;
    webKeepAlive.Elapsed += WebKeepAlive_Elapsed;
    webKeepAlive.Start();
}

private void WebKeepAlive_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    webKeepAlive.Stop();
    try
    {
        // ONLY the first time it retrieves the content it will print the string
        String finalHtml = GetWebContent();
        if (counter < 1)
        {
            Console.WriteLine(finalHtml);
        }
        counter++;
    }
    finally
    {
        webKeepAlive.Interval = 480000; // every 8 minutes
        webKeepAlive.Start();
    }
}

public String GetWebContent()
{
    try
    {
    String URL = "http://YOURURL.COM";
    WebRequest request = WebRequest.Create(URL);
    WebResponse response = request.GetResponse();
    Stream data = response.GetResponseStream();
    string html = String.Empty;
    using (StreamReader sr = new StreamReader(data))
    {
        html = sr.ReadToEnd();
    }
    Console.WriteLine (String.Format("{0} : success",DateTime.Now));
    return html;
    }
    catch (Exception ex)
    {
        Console.WriteLine (String.Format("{0} -- GetWebContent() : {1}",DateTime.Now,ex.Message));
        return "fail";
    }
}
raddevus
fuente
3

Escribir un servicio / script de ping para acceder a su sitio web inactivo es la mejor manera de hacerlo, ya que tendrá un control completo. Otras opciones que ha mencionado estarán disponibles si ha arrendado una caja de alojamiento dedicada.

En un espacio de alojamiento compartido, los scripts de calentamiento son la mejor defensa de primer nivel (la autoayuda es la mejor ayuda). Aquí hay un artículo que comparte una idea sobre cómo hacerlo desde su propia aplicación web .

David Chelliah
fuente
acabo de actualizar este viejo hilo, en caso de que alguien busque lo mismo
David Chelliah
2

Usaría B porque eso junto con el reciclaje del proceso de trabajo significa que solo habrá un retraso mientras se recicla. Esto evita el retraso normalmente asociado con la inicialización en respuesta a la primera solicitud después de inactivo. También puedes conservar los beneficios del reciclaje.

Equipo
fuente
2

Una buena opción para hacer ping al sitio en un horario es usar Microsoft Flow, que es gratis hasta 750 "ejecuciones" por mes. Es muy fácil crear un flujo que llegue a su sitio cada hora para mantenerlo caliente. Incluso puede trabajar alrededor de su límite de 750 creando un flujo único con demoras que separen múltiples visitas de su sitio.

https://flow.microsoft.com

LMK
fuente
1

Consulte este artículo para obtener consejos sobre cómo ayudar a los problemas de rendimiento. Esto incluye los dos problemas de rendimiento relacionados con el arranque, en la sección "arranque en frío". La mayor parte de esto importará sin importar qué tipo de servidor esté utilizando, localmente o en producción.

http://blogs.msdn.com/b/mcsuksoldev/archive/2011/01/19/common-performance-issues-on-asp-net-web-sites.aspx

Si la aplicación deserializa cualquier cosa desde XML (y eso incluye servicios web ...) asegúrese de que SGEN se ejecute contra todos los binarios involucrados en la deseriaización y coloque las DLL resultantes en la Caché de ensamblados global (GAC). Esto precompila todos los objetos de serialización utilizados por los ensamblados en los que se ejecutó SGEN y los almacena en caché en la DLL resultante. Esto puede generar un gran ahorro de tiempo en la primera deserialización (carga) de los archivos de configuración del disco y las llamadas iniciales a los servicios web. http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx

Si alguno de los servidores IIS no tiene acceso saliente a Internet, desactive la Lista de revocación de certificados (CRL) que busca binarios Authenticode agregando generatePublisherEvidence = "false" en machine.config. De lo contrario, los procesos de cada trabajador pueden bloquearse durante más de 20 segundos durante el inicio mientras se agota el tiempo de espera al intentar conectarse a Internet para obtener una lista de CRL. http://blogs.msdn.com/amolravande/archive/2008/07/20/startup-performance-disable-the-generatepublisherevidence-property.aspx

http://msdn.microsoft.com/en-us/library/bb629393.aspx

Considere usar NGEN en todos los ensamblajes. Sin embargo, sin un uso cuidadoso, esto no proporciona una gran ganancia de rendimiento. Esto se debe a que las direcciones de carga base de todos los archivos binarios cargados por cada proceso deben establecerse cuidadosamente en el momento de la compilación para que no se superpongan. Si los archivos binarios tienen que ser modificados cuando se cargan debido a conflictos de direcciones, se perderán casi todas las ganancias de rendimiento al usar NGEN. http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

nuzzolilo
fuente
0

Obtuve un retraso constante de 15 segundos en la primera solicitud después de 4 minutos de inactividad. Mi problema era que mi aplicación estaba usando la autenticación integrada de Windows para SQL Server y el perfil de servicio estaba en un dominio diferente al del servidor. Esto provocó una autenticación entre dominios de IIS a SQL tras la inicialización de la aplicación, y esta fue la verdadera fuente de mi retraso. Cambié a usar un inicio de sesión SQL en lugar de la autenticación de Windows. La demora se fue de inmediato. Todavía tengo todas las configuraciones de inicialización de la aplicación para ayudar a mejorar el rendimiento, pero puede que no hayan sido necesarias en mi caso.

Droobie
fuente