Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Max Instances seems to be limited to 10

Tags:

wcf

iis-7.5

I have a simple WCF service hosted in IIS7.5 exposed over a wsHttp binding using message security and InstanceContextMode.PerCall

I have a simple UI that spins up a configurable number of threads, each calling the service.

I have added the perfmon counter ServiceModel4.Instances. Regardless of the number of threads created and calling the service, perfmon shows that the service creates a maximum of 10 Instances.

My client config is as follows:

<?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>

My service config is as follows:

<?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>

The client code is as follows:

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);
    }

My service code is as follows:

[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);
    }
}

The service returns 400,400 for the number of threads.

Does anyone know why the service refused to create more that 10 instances?

If I create a copy of the service but with a a wsHttp binding that has <security mode="None"/> then the service happily created many more instances.

like image 602
Rob Bowman Avatar asked Oct 19 '11 13:10

Rob Bowman


2 Answers

Are you testing on a Windows Server or Windows 7? The reason I ask is that IIS on the client OS versions has a 10 connection limit. This is to prevent the client OS from being used in a server environment.

like image 155
Graymatter Avatar answered Oct 30 '22 21:10

Graymatter


The MaxConcurrentSessions documentation mentions an optimization for client requests that come from the same AppDomain. Your sample code is basically hitting the same socket on the service. Since there is some throttling done per client, that may be affecting your service behavior. Also, 10 happens to be the default value for MaxConcurrentSessions so it may be that your config is not changing the WCF default value.

Enabling security affects the total threads because it establishes a "session" per client so that each request sent does not need to be authenticated on every call. Those security "sessions" count toward the MaxConcurrentSessions total.

like image 26
Sixto Saez Avatar answered Oct 30 '22 22:10

Sixto Saez