Максимальное количество экземпляров WCF ограничено 10 - PullRequest
13 голосов
/ 19 октября 2011

У меня есть простая служба WCF, размещенная в IIS7.5, доступная через привязку wsHttp с использованием защиты сообщений и InstanceContextMode.PerCall

У меня есть простой пользовательский интерфейс, который раскручивает настраиваемое количество потоков, каждый из которых вызывает службу.

Я добавил счетчик перфмонов ServiceModel4.Instances.Независимо от количества потоков, созданных и вызывающих службу, perfmon показывает, что служба создает максимум 10 экземпляров.

Моя конфигурация клиента выглядит следующим образом:

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

Моя конфигурация службыследующим образом:

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

Код клиента выглядит следующим образом:

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

Мой сервисный код выглядит следующим образом:

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

Служба возвращает 400 400 длячисло потоков.

Кто-нибудь знает, почему служба отказалась создавать более 10 экземпляров?

Если я создаю копию службы, но с привязкой wsHttp, которая имеет <security mode="None"/>, тогдасервис с радостью создал еще много экземпляров.

Ответы [ 3 ]

20 голосов
/ 30 октября 2011

Вы тестируете на Windows Server или Windows 7? Причина, по которой я спрашиваю, состоит в том, что IIS в клиентских версиях ОС имеет ограничение на 10 подключений. Это необходимо для предотвращения использования клиентской ОС в серверной среде.

2 голосов
/ 20 октября 2011

В документации MaxConcurrentSessions упоминается оптимизация для клиентских запросов, поступающих из одного и того же домена приложения. Ваш пример кода в основном использует тот же сокет на сервисе. Поскольку для каждого клиента выполняется некоторое регулирование, это может повлиять на поведение службы. Кроме того, значение 10 является значением по умолчанию для MaxConcurrentSessions, поэтому может случиться так, что ваша конфигурация не изменяет значение по умолчанию WCF.

Включение защиты влияет на общее количество потоков, поскольку оно устанавливает «сеанс» для каждого клиента, так что каждый отправленный запрос не должен проходить проверку подлинности при каждом вызове. Эти «сеансы» безопасности учитываются в общем количестве MaxConcurrentSessions.

1 голос
/ 02 ноября 2011

Вы используете клиент и сервер на одной машине?Тогда они могут бороться за доступные потоки.

Если вы работаете на другом ПК, убедитесь, что вы выполнили следующие изменения конфигурации как на клиенте, так и на сервере.

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

Возможно, клиент не генерирует более 10 запросов на один и тот же сервер.Поэтому, пожалуйста, сначала попробуйте указанные выше конфиги как на клиенте, так и на сервере.

И, конечно, у вас должен быть Windows Server.В противном случае это будет предел IIS в Windows 7.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...