Tenemos una aplicación que tiene un servicio WCF (* .svc) que se ejecuta en IIS7 y varios clientes consultan el servicio. El servidor está ejecutando Win 2008 Server. Los clientes ejecutan Windows 2008 Server o Windows 2003 Server. Recibo la siguiente excepción, que he visto que de hecho puede estar relacionada con una gran cantidad de posibles problemas de WCF.
System.TimeoutException: The request channel timed out while waiting for a reply after 00:00:59.9320000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://www.domain.com/WebServices/myservice.svc/gzip' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.
Aumenté el tiempo de espera a 30 minutos y el error aún se produjo. Esto me dice que hay algo más en juego, porque la cantidad de datos nunca podría tardar 30 minutos en cargarse o descargarse.
El error va y viene. Por el momento, es más frecuente. No parece importar si tengo 3 clientes ejecutándose simultáneamente o 100, todavía ocurre de vez en cuando. La mayoría de las veces, no hay tiempos de espera, pero todavía obtengo algunos por hora. El error proviene de cualquiera de los métodos que se invocan. Uno de estos métodos no tiene parámetros y devuelve algunos datos. Otro toma muchos datos como parámetro pero se ejecuta de forma asincrónica. Los errores siempre se originan en el cliente y nunca hacen referencia a ningún código del servidor en el seguimiento de la pila. Siempre termina con:
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
En el servidor: he probado (y actualmente tengo) las siguientes configuraciones de enlace:
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"
No parece tener impacto.
Probé (y actualmente tengo) las siguientes configuraciones de aceleración:
<serviceThrottling maxConcurrentCalls="1500" maxConcurrentInstances="1500" maxConcurrentSessions="1500"/>
No parece tener impacto.
Actualmente tengo la siguiente configuración para el servicio WCF.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
Corrí con ConcurrencyMode.Multiple
por un tiempo, y el error aún se produjo.
Intenté reiniciar IIS, reiniciar mi SQL Server subyacente, reiniciar la máquina. Todos estos no parecen tener un impacto.
Intenté deshabilitar el firewall de Windows. No parece tener impacto.
En el cliente, tengo estas configuraciones:
maxReceivedMessageSize="2147483647"
<system.net>
<connectionManagement>
<add address="*" maxconnection="16"/>
</connectionManagement>
</system.net>
Mi cliente cierra sus conexiones:
var client = new MyClient();
try
{
return client.GetConfigurationOptions();
}
finally
{
client.Close();
}
He cambiado la configuración del registro para permitir más conexiones salientes:
MaxConnectionsPerServer=24, MaxConnectionsPer1_0Server=32.
Recientemente he probado SvcTraceViewer.exe. Me las arreglé para atrapar una excepción en el lado del cliente. Veo que su duración es de 1 minuto. Al observar el seguimiento del lado del servidor, puedo ver que el servidor no está al tanto de esta excepción. La duración máxima que puedo ver es de 10 segundos.
He mirado las conexiones de bases de datos activas usando exec sp_who
en el servidor. Solo tengo unos pocos (2-3). He mirado las conexiones TCP de un cliente usando TCPview. Suele rondar las 2-3 y he visto hasta 5 o 6.
En pocas palabras, estoy perplejo. He intentado todo lo que pude encontrar y debe faltar algo muy simple que un experto de WCF podría ver. Tengo la intuición de que algo está bloqueando a mis clientes en el nivel bajo (TCP), antes de que el servidor realmente reciba el mensaje y / o que algo está poniendo en cola los mensajes a nivel del servidor y nunca los deja procesar.
Si tiene algún contador de rendimiento que deba consultar, hágamelo saber. (indique qué valores son malos, ya que algunos de estos contadores son difíciles de descifrar). Además, ¿cómo podría registrar el tamaño del mensaje WCF? Finalmente, ¿hay alguna herramienta que me permita probar cuántas conexiones puedo establecer entre mi cliente y el servidor (independientemente de mi aplicación)?
¡Gracias por tu tiempo!
Información adicional agregada el 20 de junio:
Mi aplicación WCF hace algo similar a lo siguiente.
while (true)
{
Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
Step2GetWorkUnitFromServerViaWCF();
DoWorkLocally(); // takes 5-15minutes.
Step3SendBackResultsToServerViaWCF();
}
Usando WireShark, vi que cuando ocurre el error, tengo cinco retransmisiones de TCP seguidas de un restablecimiento de TCP más adelante. Supongo que el RST proviene de WCF y está matando la conexión. El informe de excepción que recibo es del tiempo de espera de Step3.
Descubrí esto mirando la secuencia tcp "tcp.stream eq 192". Luego expandí mi filtro a "tcp.stream eq 192 y http y http.request.method eq POST" y vi 6 POST durante esta transmisión. Esto parecía extraño, así que verifiqué con otra secuencia como tcp.stream eq 100. Tenía tres POST, lo que parece un poco más normal porque estoy haciendo tres llamadas. Sin embargo, cierro mi conexión después de cada llamada de WCF, por lo que habría esperado una llamada por flujo (pero no sé mucho sobre TCP).
Investigando un poco más, volqué la carga del paquete http en el disco para ver dónde estaban estas seis llamadas.
1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2
Supongo que dos clientes simultáneos están usando la misma conexión, por eso vi duplicados. Sin embargo, todavía tengo algunos problemas más que no puedo comprender:
a) ¿Por qué está dañado el paquete? Una casualidad de la red, ¿quizás? La carga está comprimida en gzip usando este código de muestra: http://msdn.microsoft.com/en-us/library/ms751458.aspx - ¿Podría el código tener errores de vez en cuando cuando se usa al mismo tiempo? Debería probar sin la biblioteca gzip.
b) ¿Por qué vería los pasos 1 y 2 ejecutándose DESPUÉS de que se agotó el tiempo de espera de la operación dañada? Me parece que estas operaciones no deberían haber ocurrido. Quizás no estoy viendo la transmisión correcta porque mi comprensión de TCP es defectuosa. Tengo otras corrientes que ocurren al mismo tiempo. Debo investigar otras transmisiones: un vistazo rápido a las transmisiones 190-194 muestra que Step3 POST tiene datos de carga útil adecuados (no corruptos). Empujándome a mirar la biblioteca gzip de nuevo.