Tengo una aplicación ASP.NET 4.0 que se ejecuta sobre IIS 7.5 en una máquina Windows Server 2008 R2 Enterprise de 64 bits con mucha RAM, CPU, disco, etc.
Con cada solicitud web, la aplicación ASP.NET establece una conexión a un servicio web backend (a través de sockets sin procesar), que se ejecuta en la misma máquina.
Problema: parece haber algo que limita el número de conexiones simultáneas al servicio web de backend. Sospechosamente, la cantidad de conexiones simultáneas llega a 16.
Encontré este artículo clave de Microsoft que explica cómo modificar la configuración de IIS para adaptarse a las aplicaciones ASP.NET que realizan muchas solicitudes de servicios web: http://support.microsoft.com/?id=821268#tocHeadRef
Seguí las recomendaciones del artículo, pero aún no tuve suerte. El escenario que es particularmente interesante es el maxconnection
escenario, que incluso salté a 999.
¿Alguna idea de qué más podría estrangular las conexiones?
Nota: Cuando elimino IIS de la mezcla y hago que los clientes se conecten directamente al servicio web de backend, felizmente abrirá tantas conexiones como necesite, así que estoy seguro de que el backend no es el cuello de botella. Debe ser algo en IIS / ASP.NET-land.
Aquí está la sección relevante de la machine.config
que estoy seguro que está siendo leída por la aplicación (verificada con appcmd.exe
):
<system.web>
<processModel autoConfig="false" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" />
<httpRuntime minFreeThreads="176" minLocalRequestFreeThreads="152"/>
<httpHandlers />
<membership>
<providers>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
</providers>
</membership>
<profile>
<providers>
<add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</profile>
<roleManager>
<providers>
<add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="AspNetWindowsTokenRoleProvider" applicationName="/"
type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
</system.web>
<system.net>
<connectionManagement>
<add address="*" maxconnection="999"/>
</connectionManagement>
</system.net>
fuente
Respuestas:
La mayoría de las respuestas proporcionadas aquí abordan la cantidad de solicitudes entrantes a su servicio web backend, no la cantidad de solicitudes salientes que puede realizar desde su aplicación ASP.net a su servicio backend.
No es su servicio web backend el que está limitando su tasa de solicitud aquí, es la cantidad de conexiones abiertas que su aplicación de llamadas está dispuesta a establecer al mismo punto final (misma URL).
Puede eliminar esta limitación agregando la siguiente sección de configuración a su archivo machine.config:
Por supuesto, puede elegir un número más razonable si lo desea, como 50 o 100 conexiones simultáneas. Pero lo anterior lo abrirá hasta el máximo. También puede especificar una dirección específica para la regla de límite de apertura anterior en lugar del '*' que indica todas las direcciones.
Documentación de MSDN para System.Net.connectionManagement
Otro gran recurso para comprender ConnectManagement en .NET
¡Espero que esto resuelva tu problema!
EDITAR: Vaya, veo que tiene la administración de conexión mencionada en su código anterior. Dejaré mi información anterior ya que es relevante para futuros usuarios con el mismo problema. Sin embargo, tenga en cuenta que actualmente hay 4 archivos machine.config diferentes en la mayoría de los servidores actualizados.
Hay .NET Framework v2 que se ejecuta en 32 y 64 bits, así como .NET Framework v4 también se ejecuta en 32 y 64 bits. Dependiendo de la configuración elegida para su grupo de aplicaciones, ¡podría estar usando cualquiera de estos 4 archivos machine.config diferentes! Compruebe los 4 archivos machine.config que normalmente se encuentran aquí:
fuente
machine.config
(64 bits 4.0).Me doy cuenta de que la pregunta puede ser bastante antigua, pero usted dice que el backend se ejecuta en el mismo servidor. Eso significa en un puerto diferente, probablemente diferente al puerto predeterminado 80.
Leí que cuando usa el elemento de configuración "connectionManagement", debe especificar el número de puerto si difiere del 80 predeterminado.
ENLACE: la configuración de maxConnection puede no funcionar incluso autoConfig = false en ASP.NET
En segundo lugar, si elige usar la configuración predeterminada (dirección = "*") extendida con su propio valor específico de backend, ¡podría considerar poner el valor específico primero! De lo contrario, si se realiza una solicitud, el * coincide primero y se toma el valor predeterminado de 2 conexiones. Al igual que cuando usa la sección en web.config.
ENLACE: <remove> Elemento para la gestión de conexiones (Configuración de red)
Espero que ayude a alguien.
fuente
¿Es posible que esté utilizando una referencia de servicio web basada en WCF? De forma predeterminada, ServiceThrottlingBehavior.MaxConcurrentCalls es 16.
Podría intentar actualizar el
<serviceThrottling>
elemento de comportamiento de referencia de su servicio(Tenga en cuenta que recomendaría la configuración anterior). Consulte MSDN para obtener más información sobre cómo configurar un
<behavior>
elemento apropiado .fuente
TcpClient
(el servicio vende blobs binarios personalizados, no WCF / SOAP o similar). Esas opciones de configuración parecen afectarle puramente si usaServiceHost
, noTcpClient
; ¿Me estoy perdiendo de algo?¿Ha intentado establecer el valor de la propiedad estática DefaultConnectionLimit mediante programación?
Aquí hay una buena fuente de información sobre ese verdadero dolor de cabeza ... Uso de subprocesos de ASP.NET en IIS 7.5, IIS 7.0 e IIS 6.0 , con actualizaciones para el marco 4.0.
fuente
Consulte la sección "Subprocesamiento" de esta página: http://msdn.microsoft.com/en-us/library/ff647786.aspx , junto con la sección "Conexiones".
¿Ha intentado aumentar el atributo maxconnection de su configuración processModel?
fuente
maxconnection
atributo no se aplica a las llamadas de servicios web locales . En este caso particular el servicio web es local, pero tenemos ese mismo problema en otro entorno donde el servicio no es local.minLocalRequestFreeThreads
: este proceso de trabajo usa esta configuración para poner en cola las solicitudes de localhost (donde una aplicación web llama a un servicio web en el mismo servidor ) si el número de subprocesos disponibles en el grupo de subprocesos cae por debajo de este número. Esta configuración es similar a minFreeThreads, pero solo se aplica a las solicitudes que usan localhost .minLocalRequestFreeThreads
(ver mimachine.config
en la pregunta.Si no está definido en el servicio web, la aplicación o el servidor (apache o IIS) que aloja el consumible del servicio web, puede crear infinitas conexiones hasta que falle
fuente
mientras hago las pruebas de rendimiento, la medida que sigo es RPS, es decir, cuántas solicitudes por segundo puede atender el servidor dentro de una latencia aceptable.
teóricamente, un servidor solo puede ejecutar tantas solicitudes al mismo tiempo como cantidad de núcleos en él.
No parece que el problema sea el modelo de subprocesamiento de ASP.net, ya que potencialmente puede servir miles de rps. Parece que el problema podría ser tu aplicación. ¿Está utilizando primitivas de sincronización?
también cuál es la latencia en sus servicios web, si responden muy rápido (en microsegundos), si no es así, es posible que desee considerar las llamadas asincrónicas, para que no termine bloqueando
Si esto no sirve de nada, entonces es posible que desee perfilar su código usando Visual Studio o Redgate Profiler.
fuente