Contención, mal rendimiento e interbloqueos cuando hace llamadas a servicios Web desde una aplicación ASP.NET

Seleccione idioma Seleccione idioma
Id. de artículo: 821268 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Síntomas

Al realizar llamadas a servicios Web desde una aplicación de Microsoft ASP.NET, puede experimentar contención, mal rendimiento e interbloqueos. Los clientes pueden decir que las solicitudes de dejar de responder (o "se bloquea") o tomar mucho tiempo para ejecutar. Si se sospecha que un interbloqueo, el proceso de trabajo se pueden reciclar. Puede recibir los siguientes mensajes en el registro de sucesos de aplicación.
  • Si utiliza servicios de Internet Information Server (IIS) 5.0, recibirá los mensajes siguientes en el registro de aplicación:

       Event Type:     Error
       Event Source:   ASP.NET 1.0.3705.0
       Event Category: None
       Event ID:       1003
       Date:           5/4/2003
       Time:           6:18:23 PM
       User:           N/A
       Computer:       <ComputerName>
       Description:
          aspnet_wp.exe  (PID: <xxx>) was recycled because it was suspected to be in a deadlocked state.
          It did not send any responses for pending requests in the last 180 seconds.

  • Si está utilizando IIS 6.0, recibirá los mensajes siguientes en el registro de aplicación:

       Event Type:     Warning
       Event Source:   W3SVC-WP
       Event Category: None
       Event ID:       2262
       Date:           5/4/2003
       Time:           1:02:33 PM
       User:           N/A
       Computer:       <ComputerName>
       Description:
          ISAPI 'C:\Windows\Microsoft.net\Framework\v.1.1.4322\aspnet_isapi.dll' reported itself as
          unhealthy for the following reason: 'Deadlock detected'.

  • Si está utilizando IIS 6.0, recibirá los mensajes siguientes en el registro del sistema:

       Event Type:     Warning
       Event Source:   W3SVC
       Event Category: None
       Event ID:       1013
       Date:           5/4/2003
       Time:           1:03:47 PM
       User:           N/A
       Computer:       <ComputerName>
       Description:
          A process serving application pool 'DefaultAppPool' exceeded time limits during shut down.
          The process id was '<xxxx>'.

También puede recibir el siguiente mensaje de error de excepción al realizar una llamada al método HttpWebRequest.GetResponse :
"System.InvalidOperationException: no había suficientes subprocesos libres en el objeto ThreadPool para completar la operación."
También puede recibir el siguiente mensaje de error de excepción en el explorador:
"HttpException (0 x 80004005): solicitud agotado."
Nota En este artículo también se aplica a las aplicaciones que realizan solicitudes de HttpWebRequest directamente.

Causa

Este problema puede producirse porque ASP.NET limita el número de subprocesos de trabajo y subprocesos de puerto de finalización que una llamada puede utilizar para ejecutar las solicitudes.

Normalmente, una llamada a un servicio Web utiliza un subproceso de trabajo para ejecutar el código que envía la solicitud y un subproceso de puerto de finalización para recibir la devolución de llamada del servicio Web. Sin embargo, si la solicitud se redirige o requiere autenticación, la llamada puede utilizar hasta dos subprocesos de trabajo y dos subprocesos de puerto de finalización. Por lo tanto, puede agotar el objeto ThreadPool administrado cuando se producen varias llamadas a servicios Web al mismo tiempo.

Por ejemplo, suponga que ThreadPool está limitado a 10 subprocesos de trabajo y que todos 10 subprocesos de trabajo están ejecutando actualmente código que está esperando una devolución de llamada ejecutar. La devolución de llamada nunca puede ejecutarse porque los elementos de trabajo que están en cola en el grupo de subprocesos se bloquean hasta que un subproceso esté disponible.

Otro origen posible de contención es el parámetro de maxconnection que utiliza el espacio de nombres System.Net para limitar el número de conexiones. Generalmente, este límite funciona como se esperaba. Sin embargo, si muchas aplicaciones intentan realizar muchas solicitudes a una única dirección IP al mismo tiempo, los subprocesos deban esperar una conexión disponible.

Solución

Para resolver estos problemas, puede ajustar los siguientes parámetros en el archivo Machine.config que mejor se ajusten a su situación:
  • maxWorkerThreads
  • minWorkerThreads
  • maxIoThreads
  • minFreeThreads
  • minLocalRequestFreeThreads
  • maxconnection
  • executionTimeout
Para solucionar estos problemas, realice las acciones siguientes:
  • Limitar el número de solicitudes ASP.NET que se pueden ejecutar al mismo tiempo a 12 por CPU aproximadamente.
  • Permitir que las devoluciones de llamada de servicio de Web utilicen libremente los subprocesos en el grupo de subprocesos.
  • Seleccione un valor adecuado para el parámetro maxconnections . Base su selección en el número de andAppDomains de direcciones IP que se utilizan.
Nota La recomendación para limitar el número de solicitudes ASP.NET a 12 por CPU es algo arbitraria. Sin embargo, este límite ha demostrado funcionar bien para la mayoría de las aplicaciones.

maxWorkerThreads y maxIoThreads

ASP.NET utiliza los siguientes valores de configuración para limitar el número máximo de subprocesos de trabajo y subprocesos de finalización que se utilizan:
<processModel maxWorkerThreads="20" maxIoThreads="20">
El parámetro maxWorkerThreads y maxIoThreads se multiplican implícitamente por el número de CPU. Por ejemplo, si tiene dos procesadores, el número máximo de subprocesos de trabajo es el siguiente:
2 * maxWorkerThreads

minFreeThreads y minLocalRequestFreeThreads

ASP.NET también contiene las opciones de configuración siguientes que determinan cuántos subprocesos de trabajo y subprocesos de puerto de finalización deben haber disponibles para iniciar una solicitud remota o una solicitud local:
<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="8">
Si no hay suficientes subprocesos disponibles, la solicitud se pone en cola hasta que los subprocesos suficientes son libres realizar la solicitud. Por lo tanto, ASP.NET no ejecutará más que el número de solicitudes siguiente al mismo tiempo:
(maxWorkerThreads*número de CPU)-minFreeThreads
Nota El parámetro minFreeThreads y minLocalRequestFreeThreads no se multiplican implícitamente por el número de CPU.

minWorkerThreads

A partir del Service Pack 3 de ASP.NET 1.0 y ASP.NET 1.1, ASP.NET también contiene la opción de configuración siguiente que determina cuántos subprocesos de trabajo estarán disponibles inmediatamente para atender una solicitud remota.
<processModel minWorkerThreads="1">
Los subprocesos controlados por esta opción pueden crearse a una velocidad mucho más rápida que los subprocesos de trabajo que se crean a partir de funciones de "ajuste de subprocesos" de CLR predeterminadas. Este permite ASP.NET al servicio de solicitudes que puede llenar repentinamente la cola de solicitudes ASP.NET debido a un retraso en un servidor de servicios de fondo, una ráfaga súbita de solicitudes de cliente o algo similar que provocaría un brusco aumento en el número de solicitudes en la cola. El valor predeterminado para el parámetro minWorkerThreads es 1. Se recomienda que establezca el valor para el parámetro minWorkerThreads en el valor siguiente.
minWorkerThreads = maxWorkerThreads / 2
De manera predeterminada, el parámetro minWorkerThreads no está presente en el archivo Web.config o Machine.config. Esta configuración se multiplica implícitamente por el número de CPU.

maxconnection

El parámetro maxconnection determina cuántas conexiones pueden realizarse a una dirección IP específica. El parámetro aparece como sigue:
<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://65.53.32.230" maxconnection="12">
</connectionManagement>
Si el código de la aplicación hace referencia a la aplicación por nombre de host en lugar de la dirección IP, el parámetro debe aparecer como sigue:
<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://hostname" maxconnection="12">
</connectionManagement>
Por último, si la aplicación está hospedada en un puerto distinto de 80, el parámetro debe incluir el puerto no estándar en el URI, similar a la siguiente:
<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://hostname:8080" maxconnection="12">
</connectionManagement>
Los valores para los parámetros que se han descrito anteriormente en este artículo son todo en el nivel de proceso. Sin embargo, el valor del parámetro maxconnection se aplica en el nivel de dominio de aplicación. De manera predeterminada, porque esta configuración se aplica en el nivel de dominio de aplicación, puede crear un máximo de dos conexiones a una dirección IP concreta desde cada dominio de aplicación en el proceso.

executionTimeout

ASP.NET utiliza la opción de configuración siguiente para limitar el tiempo de ejecución de solicitud:
<httpRuntime executionTimeout="90"/>
También puede establecer este límite mediante la propiedad Server.ScriptTimeout .

Nota Si aumenta el valor del parámetro executionTimeout , también tendrá que modificar el valor del parámetro processModel responseDeadlockInterval .

Recomendaciones

La configuración que se recomienda en esta sección no funcionen en todas las aplicaciones. Sin embargo, la siguiente información adicional puede ayudarle a realizar los ajustes oportunos.

Si va a realizar una llamada de servicio Web a una única dirección IP desde cada página ASPX, Microsoft recomienda que utilice la configuración siguiente:
  • Establecer los valores de los parámetros maxWorkerThreads y maxIoThreads a 100.
  • Establezca el valor del parámetro maxconnection12 *N (donde N es el número de CPUs recomiendautilizar la tienen).
  • Establecer los valores del parámetro minFreeThreads88 *N y el parámetro minLocalRequestFreeThreads para76 *N.
  • Fijar el valor de minWorkerThreads a 50. Recuerde, minWorkerThreads no está en el archivo de configuración por defecto. Se debe agregar.
Algunas de estas recomendaciones implican una fórmula sencilla que consiste en el número de CPU en un servidor. Es la variable que representa el número de CPU en las fórmulas N. Para esta configuración, si tiene hyperthreading habilitado, debe utilizar el número de CPU lógicas en lugar del número de CPU físicas. Por ejemplo, si tiene un servidor de cuatro procesadores con hyperthreading habilitado, entonces el valor de N en las fórmulas será 8 en lugar de 4.

Nota Cuando se utiliza esta configuración, un máximo de 12 solicitudes ASP.NET por CPU pueden ejecutar al mismo tiempo porque 100-88 = 12. Por lo tanto, al menos 88 *N los subprocesos de trabajo y 88 *N subprocesos de puerto de finalización están disponibles para otros usos (como las devoluciones de llamada de servicio Web).

Por ejemplo, tiene un servidor con cuatro procesadores e hyperthreading está habilitado. Según estas fórmulas, utilizaría los siguientes valores para las opciones de configuración que se mencionan en este artículo.
<system.web>
	<processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50"/>
	<httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"/>
</system.web>

<system.net>
	<connectionManagement>
		<add address="[ProvideIPHere]" maxconnection="96"/>
	</connectionManagement>
</system.net>

Además, cuando se utiliza esta configuración, 12 conexiones están disponibles por CPU por dirección IP para cada dominio de aplicación. Por lo tanto, en el siguiente escenario, muy poca contención se produce cuando las solicitudes en espera de conexiones y no se ha agotado ThreadPool:
  • El web sólo aloja una aplicación (AppDomain).
  • Cada solicitud de una página ASPX realiza una solicitud de servicio Web.
  • Todas las solicitudes son para la misma dirección IP.
Sin embargo, cuando se utiliza esta configuración, los escenarios que implican uno de los siguientes probablemente utilizarán demasiadas conexiones:
  • Solicitudes van dirigidas a varias direcciones IP.
  • Las solicitudes están redirigidas (código de estado 302).
  • Las solicitudes requieren autenticación.
  • Las solicitudes se realizan desde varios dominios de aplicación.
En estos casos, es una buena idea utilizar un valor inferior para el parámetro maxconnection y valores más altos para los parámetros minFreeThreads y minLocalRequestFreeThreads .

Estado

Este comportamiento es por diseño.

Más información

Si experimenta un rendimiento deficiente y contención en IIS 7.0, junto con ASP.NET, visite los blogs de Microsoft siguientes:
Uso de subprocesos de ASP.NET en IIS 6.0, IIS 7.0 y IIS 7.5

Bloqueo de ASP.net en IIS 7.0

Referencias

Para obtener más información, visite el siguiente sitio Web de Microsoft Developer Network (MSDN):
Mejorar el rendimiento de ASP.NET

Propiedades

Id. de artículo: 821268 - Última revisión: sábado, 23 de noviembre de 2013 - Versión: 2.0
La información de este artículo se refiere a:
  • Microsoft .NET Framework 2.0
  • Microsoft ASP.NET 1.1
  • Microsoft ASP.NET 1.0
Palabras clave: 
kbprb kbmt KB821268 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 821268

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com