visual test studio servicio publicar paso example crear configurar wcf multithreading concurrency throttling

test - Solicitudes concurrentes de WCF acumuladas en el servidor cuando se usa WSHttpBinding



wcf test client visual studio 2017 (8)

Considere usar ConcurrencyMode.Multiple en los servicios por llamada para permitir llamadas concurrentes.

Tengo una aplicación cliente / servidor WCF que se comunica a través de HTTP usando WSHttpBinding.

Configuración del servidor : autohospedaje, utilizando el WCF ServiceHost estándar. Mi clase de servicio real se atribuye a:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerSession, UseSynchronizationContext = false)]

Configuración del cliente : utilizando un proxy del cliente generado por el visual-studio utilizando llamadas de servicio síncronas ( proxy.call_server_method bloquea hasta que el servidor haya respondido por completo).

Escenario : Tengo una llamada de método particular que tarda 20 segundos en ejecutarse en el servidor. El cliente llama a este método en un subproceso separado, por lo que no se mantiene, y ConcurrencyMode.Multiple significa que WCF debería ejecutarlo en un subproceso separado en el servidor también.

Esta teoría es respaldada por el hecho de que cuando configuro mi aplicación para usar NetTcpBinding , todo funciona bien.

Problema :
Si configuro la aplicación para usar WSHttpBinding , esta larga llamada de método hace que las solicitudes http '' WSHttpBinding copia de seguridad''. He verificado este comportamiento tanto al inspeccionar mis registros como al depurar las solicitudes HTTP usando el violín.

Ejemplo:

  • El cliente inicia una solicitud larga de 20 segundos en un hilo de fondo
  • El cliente inicia la solicitud B y C en el hilo de primer plano
  • Las solicitudes B y C se envían al servidor, que no las procesa hasta que se completa con la solicitud larga de 20 segundos

Pero a veces:

  • Las solicitudes B y C no se envían (ni siquiera aparecen en el violín) hasta que vuelve la solicitud de 20 segundos (esto es raro).
    • Nota: establecer <add address="*" maxconnection="100"/> en la aplicación del cliente .config hizo que esto (parezca) deje de suceder.
  • La solicitud B se envía y recibe una respuesta de inmediato, mientras que la solicitud C se retiene hasta que finaliza la de 20 segundos (esto es raro)

Aquí hay una línea de tiempo de fiddler que demuestra el problema: (haga clic para una versión más grande)

Como puede ver, todas las solicitudes están respaldadas en el servidor. Una vez que se completa la solicitud de 20 segundos, todas las respuestas se abren paso, pero tenga en cuenta que hay algunas solicitudes que no se retrasan ...

Entonces, preguntas :

  • ¿Qué diablos está pasando aquí? ¿Por qué funciona bien usando NetTcpBinding y no funciona usando WSHttpBinding ?
  • ¿Por qué el comportamiento inconsistente?
  • ¿Que puedo hacer para arreglarlo?

Notas:

  • No se está bloqueando en el servidor. Establecí puntos de corte y usé !syncblk e informa consistentemente que no se están !syncblk .
  • No es mi threading (NetTcpBinding no debería funcionar de otra manera)
  • Tengo <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" /> establecido en el servidor app.config
  • La llamada de 20 segundos solo está esperando en un temporizador, no está acelerando la CPU o el disco o la red
  • Preferiría una solución que no implicara volver a diseñar la aplicación para usar llamadas asíncronas ... es un gran grupo de código heredado y realmente no quiero meterme con cosas que no entiendo.


Hay algo de aceleración fuera de WCF (una cosa de .Net o Windows) que de forma predeterminada solo permite un máximo de dos conexiones HTTP de salida simultáneas. Lamentablemente, no recuerdo el nombre de la cosa (y lo que pondrías en app.config o tu aplicación para anularla). Dado que no ve que las solicitudes abandonan al cliente, y que solo es HTTP, creo que está presionando "esa cosa". Seguiré buscando su nombre.

Actualización: lo encontré - prueba esto en el cliente (pero cambia el ''2'' a un número mayor):

<configuration> <system.net> <connectionManagement> <add address = "*" maxconnection = "2" /> </connectionManagement> </system.net> </configuration>


Me olvido, ¿podría estar ordenando? Creo que tal vez la RM sobre http conserva el orden pero tal vez las sesiones Tcp no lo hagan (a menos que lo solicite explícitamente). ¿Hay algún atributo en el Contrato de Servicio que describa las sesiones ordenadas / desordenadas (lo olvido)?



Si cambia a BasicHttpBinding, ¿funciona?

Es así, parece que este es tu problema , estrangulamiento de sesión, algo que me mordió el culo.


Vimos exactamente los mismos síntomas con un servicio JSON alojado en IIS / ASP.NET.

La causa raíz terminó siendo ASP.NET sincronizando las solicitudes, no WCF. Tuvimos que deshabilitar el estado de la sesión (en el nivel de la aplicación) para obtener métodos concurrentes de WCF.

Web.config: <system.web> <sessionState mode="Off" /> </system.web>

Tenga en cuenta que nuestro servicio utiliza webHttpBinding, no wsHttpBinding. Entonces, no estoy seguro de si esto también resuelve el problema de Orión.


[Respuesta propia para mostrar a otros usuarios cuál fue nuestra solución final]

Al final, nunca logré resolver esto.
Nuestra solución final fue cambiar nuestra aplicación de WSHttpBinding a NetTcpBinding en producción; al WSHttpBinding y al NetTcpBinding , habíamos estado planeando hacer esto por cuestiones de rendimiento.

Sin embargo, esto es bastante desafortunado, ya que deja una marca negra en WSHttpBinding que puede estar justificada o no. Si alguna vez se llega a una solución que no implique abandonar WSHttpBinding , me encantaría saberlo