2011-10-19 8 views
13

Tengo un servicio de WCF sencilla alojado en IIS7.5 expuesta durante un wsHttp unión usando seguridad de los mensajes y InstanceContextMode.PerCallinstancias WCF Max parece estar limitada a 10

que tienen una interfaz de usuario simple que hace girar un número configurable de hilos, cada uno llamando al servicio.

He agregado el contador perfmon ServiceModel4.Instances. Independientemente de la cantidad de subprocesos creados y de llamar al servicio, perfmon muestra que el servicio crea un máximo de 10 instancias.

Mi config cliente es el siguiente:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 

    <bindings> 
    <wsHttpBinding> 

     <binding name="WSHttpBinding_IService3"> 
     <security mode="Message"> 
      <transport clientCredentialType="Windows" proxyCredentialType="None" 
      realm="" /> 
      <message clientCredentialType="Windows" negotiateServiceCredential="true" 
      algorithmSuite="Default" establishSecurityContext="false" /> 
     </security> 
     </binding> 

    </wsHttpBinding> 
    </bindings> 
    <client> 

    <endpoint address="http://localhost/NGCInstancing/Service3.svc/~/Service3.svc" 
     binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService3" 
     contract="NGCSecPerCall.IService3" name="WSHttpBinding_IService3"> 
     <identity> 
     <servicePrincipalName value="host/RB-T510" /> 
     </identity> 
    </endpoint> 

    </client> 
</system.serviceModel> 
</configuration> 

Mi config servicio es como sigue:

<?xml version="1.0"?> 
<system.serviceModel> 
    <configuration> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name="SecPerCallBehaviour"> 
        <serviceThrottling maxConcurrentCalls="30" maxConcurrentSessions="1000" 
        maxConcurrentInstances="30" /> 
        <serviceMetadata httpGetEnabled="true" /> 
        <serviceDebug includeExceptionDetailInFaults="false" /> 
       </behavior> 
       <behavior name=""> 
        <serviceMetadata httpGetEnabled="true" /> 
        <serviceDebug includeExceptionDetailInFaults="false" /> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
    <bindings> 
     <wsHttpBinding> 
      <binding name="BindingMessageSecPerCall" > 
      <security mode="Message"> 
      <!-- it's by setting establishSecurityContext to false that we enable per call instancing with security --> 
      <message establishSecurityContext="false" /> 
      </security> 
      </binding> 
     </wsHttpBinding> 
    </bindings> 
    <services> 
     <service name="ServiceInstancingDemo.Service3" behaviorConfiguration="SecPerCallBehaviour"> 
     <endpoint address="~/Service3.svc" 
     binding="wsHttpBinding" bindingConfiguration="BindingMessageSecPerCall" 
     contract="ServiceInstancingDemo.IService3" /> 
     </service> 
    </services> 
    </configuration> 
</system.serviceModel> 

El código de cliente es el siguiente:

private void btnSecPerCall_Click(object sender, EventArgs e) 
    { 
     int i; 
     int requests; 
     int delay; 

     lblStatus.Text = ""; 

     DateTime startTime = DateTime.Now; 
     this.listBox1.Items.Add("start time=" + DateTime.Now); 

     delay = Convert.ToInt16(txtDelay.Text); 
     requests = Convert.ToInt16(txtRequests.Text); 

     Task<string>[] result; 
     result = new Task<string>[requests]; 

     for (i = 0; i < requests; i++) 
     { 
      result[i] = Task<string>.Factory.StartNew(() => _ngcSecPerCall.WaitThenReturnString(delay)); 
     } 

     for (i = 0; i < requests; i++) 
     { 
      this.listBox1.Items.Add(result[i].Result); 
     } 

     DateTime endTime = DateTime.Now; 
     TimeSpan ts = endTime - startTime; 
     lblStatus.Text = "Finished! Time taken= " + ts.Seconds + " seconds"; 

     this.listBox1.Items.Add("end time=" + DateTime.Now); 
    } 

Mi código de servicio es de la siguiente manera:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
public class Service3 : IService3 
{ 
    private int m_counter; 

    public string WaitThenReturnString(int waitMilliSeconds) 
    { 
     System.Threading.Thread.Sleep(waitMilliSeconds); 
     int maxT, workCT; 
     System.Threading.ThreadPool.GetMaxThreads(out maxT, out workCT); 
     m_counter++; 
     return String.Format("Incrementing counter to {0}.\r\nSession Id: {1}. Threads {2}, {3}", m_counter, OperationContext.Current.SessionId, maxT, workCT); 
    } 
} 

El servicio devuelve 400,400 por el número de subprocesos.

¿Alguien sabe por qué el servicio se negó a crear más de 10 instancias?

Si creo una copia del servicio pero con un enlace wsHttp que tiene <security mode="None"/> entonces el servicio felizmente creó muchas más instancias.

Respuesta

20

¿Está probando en un servidor Windows o Windows 7? La razón por la que pregunto es que IIS en las versiones del sistema operativo del cliente tiene un límite de 10 conexiones. Esto es para evitar que el sistema operativo del cliente se use en un entorno de servidor.

+0

¡Esto suena prometedor! Estoy usando Windows 7. Mañana implementaré en una máquina virtual win2008 y regresaré. –

+1

Sí, eso fue todo. Cuando pruebo en la máquina virtual Win 2008 funciona bien. Muchas gracias Graymatter –

2

El MaxConcurrentSessions documentation menciona una optimización para solicitudes de clientes que provienen del mismo dominio de aplicación. Su código de muestra básicamente está llegando al mismo socket en el servicio. Debido a que hay un límite por cliente, eso puede estar afectando su comportamiento de servicio. Además, 10 pasa a ser el valor predeterminado para MaxConcurrentSessions, por lo que es posible que su configuración no cambie el valor predeterminado de WCF.

La habilitación de la seguridad afecta al total de subprocesos porque establece una "sesión" por cliente para que cada solicitud enviada no necesite ser autenticada en cada llamada. Esas "sesiones de seguridad" cuentan para el total de MaxConcurrentSessions.

+0

Merece la pena agregar que he implementado el mismo servicio con un enlace diferente.El nuevo enlace también es wsHttp pero tiene . Cuando ejecuto el mismo cliente contra este servicio, el servicio felizmente genera más de 10 instancias. Supongo que para el nuevo enlace las sesiones no se están utilizando porque no hay necesidad de establecer un contexto de seguridad. Creo que estás en lo cierto con el hecho de que 10 es el MaxConcurrentSessions predeterminado, pero por supuesto mi configuración intenta cambiar este valor a 1000. ¿Alguien sabe cómo comprobar la configuración real utilizada en el tiempo de ejecución? –

+0

Moví mis pruebas a una máquina virtual Win2008 y ahora funciona de maravilla: obtengo 61 instancias en lugar de las 10 que recibía en mi servidor Win7. Muchas gracias Sixto Saez! –

1

¿Está ejecutando el cliente y el servidor en la misma máquina? Entonces podrían estar luchando por los hilos disponibles.

Si está ejecutando en una PC diferente, asegúrese de haber realizado los siguientes cambios de configuración tanto en el cliente como en el servidor.

http://www.codeproject.com/KB/webservices/quickwins.aspx

Es posible que el cliente no está generando más de 10 peticiones al mismo servidor. Por lo tanto, intente primero las configuraciones anteriores tanto en el cliente como en el servidor.

Y, por supuesto, debe tener un servidor de Windows. De lo contrario, será el límite de IIS en Windows 7.

Cuestiones relacionadas