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.
fuente
Respuestas:
Si está utilizando el cliente .Net, es posible que no haya configurado
aquí está la pregunta original y la respuesta WCF Service Throttling
Actualización :
Esta configuración va en la aplicación cliente .Net puede estar en el inicio o cuando sea, pero antes de comenzar sus pruebas.
Además, puede tenerlo en el archivo app.config, así como seguir
fuente
Si aún no lo ha probado, encapsule sus operaciones WCF del lado del servidor en bloques try / finalmente, y agregue el registro para asegurarse de que realmente estén regresando.
Si muestran que las Operaciones se están completando, entonces mi siguiente paso sería ir a un nivel inferior y mirar la capa de transporte real.
Wireshark u otra herramienta de captura de paquetes similar puede ser muy útil en este momento. Supongo que esto se ejecuta a través de HTTP en el puerto estándar 80.
Ejecute Wireshark en el cliente. En las Opciones, cuando inicie la captura, configure el filtro de captura en
tcp http and host service.example.com
: esto reducirá la cantidad de tráfico irrelevante.Si puede, modifique su cliente para que le notifique la hora exacta de inicio de la llamada y la hora en que se agotó el tiempo de espera. O simplemente vigílelo de cerca.
Cuando recibe un error, puede rastrear los registros de Wireshark para encontrar el inicio de la llamada. Haga clic con el botón derecho en el primer paquete que tiene su cliente llamando (debería ser algo como GET /service.svc o POST /service.svc) y seleccione Seguir TCP Stream.
Wireshark decodificará toda la conversación HTTP, por lo que puede asegurarse de que WCF realmente está enviando respuestas.
fuente
de: http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx
fuente
Tengo un problema muy similar. En el pasado, esto se ha relacionado con problemas de serialización. Si aún tiene este problema, ¿puede verificar que puede serializar correctamente los objetos que está devolviendo? Específicamente, si está utilizando objetos Linq-To-Sql que tienen relaciones, existen problemas de serialización conocidos si coloca una referencia hacia atrás en un objeto secundario al objeto principal y marca esa referencia hacia atrás como un DataMember.
Puede verificar la serialización escribiendo una aplicación de consola que serialice y deserialice sus objetos usando DataContractSerializer en el lado del servidor y cualquier método de serialización que use su cliente. Por ejemplo, en nuestra aplicación actual, tenemos clientes de WPF y Compact Framework. Escribí una aplicación de consola para verificar que puedo serializar usando un DataContractSerializer y deserializar usando un XmlDesserializer. Puede intentarlo.
Además, si devuelve objetos Linq-To-Sql que tienen colecciones secundarias, puede intentar asegurarse de haberlos cargado con entusiasmo en el lado del servidor. A veces, debido a la carga diferida, los objetos que se devuelven no se completan y pueden causar el comportamiento que está viendo donde la solicitud se envía al método de servicio varias veces.
Si ha resuelto este problema, me encantaría saber cómo, porque yo también estoy atascado. He verificado que mi problema no es la serialización, por lo que estoy perdido.
ACTUALIZACIÓN: No estoy seguro de si le ayudará en algo, pero la herramienta Service Trace Viewer Tool acaba de resolver mi problema después de 5 días de experiencia muy similar a la suya. Al configurar el rastreo y luego mirar el XML sin procesar, encontré las excepciones que estaban causando mis problemas de serialización. Estaba relacionado con los objetos Linq-to-SQL que ocasionalmente tenían más objetos secundarios de los que podían serializarse correctamente. Agregar lo siguiente a su archivo web.config debería habilitar el seguimiento:
El archivo resultante se puede abrir con la herramienta Service Trace Viewer Tool o simplemente en IE para examinar los resultados.
fuente
¿Está cerrando la conexión al servicio WCF entre solicitudes? Si no lo hace, verá este tiempo de espera exacto (eventualmente).
fuente
Acabo de resolver el problema. Descubrí que los nodos en el archivo App.config se han confijado incorrectamente.
Confirme su configuración en el nodo
<security>
, el valor del atributo "modo" es "Ninguno". Si su valor es "Transporte", se produce el error.fuente
¿ Intentó usar clientVia para ver el mensaje enviado, usando el kit de herramientas SOAP o algo así? Esto podría ayudar a ver si el error proviene del propio cliente o de algún otro lugar.
fuente
deprecated
¿Comprobó los seguimientos de WCF? WCF tiende a tragar excepciones y solo devolver la última excepción, que es el tiempo de espera que está obteniendo, ya que el punto final no devolvió nada significativo.
fuente
También recibirá este error si está devolviendo un objeto al cliente que contiene una propiedad de tipo enum que no está establecida de forma predeterminada y que enum no tiene un valor que se asigne a 0. es decir,
enum MyEnum{ a=1, b=2};
fuente
Parece que este mensaje de excepción es bastante genérico y se puede recibir debido a una variedad de razones. Nos encontramos con esto al implementar el cliente en máquinas con Windows 8.1. Nuestro cliente WCF se ejecuta dentro de un servicio de Windows y sondea continuamente el servicio WCF. El servicio de Windows se ejecuta bajo un usuario que no es administrador. El problema se solucionó configurando clientCredentialType en "Windows" en la configuración de WCF para permitir el paso de la autenticación, como se muestra a continuación:
fuente
No soy un experto en WCF, pero me pregunto si no se está encontrando con una protección DDOS en IIS. Sé por experiencia que si ejecuta un montón de conexiones simultáneas desde un solo cliente a un servidor en algún momento, el servidor deja de responder a las llamadas ya que sospecha de un ataque DDOS. También mantendrá las conexiones abiertas hasta que se agoten para ralentizar al cliente en sus ataques.
Sin embargo, la conexión múltiple proveniente de diferentes máquinas / IP no debería ser un problema.
Hay más información en esta publicación de MSDN:
http://msdn.microsoft.com/en-us/library/bb463275.aspx
Consulte la propiedad MaxConcurrentSession.
fuente