Поток потока при связывании net.tcp - код ошибки TCP 10061

Я столкнулся с очень странной ошибкой в ​​моей службе WCF, которая, кажется, каким-то образом создает тупик или истощение потоков на уровне сокетов при использовании NetTcpBinding. У меня есть довольно простой сервис самостоятельно:

class Program
{
    static void Main(string[] args)
    {
        using (ServiceHost serviceHost = new ServiceHost(typeof(TestService)))
        {
            serviceHost.Open();             
            Console.WriteLine("Press <ENTER> to terminate service.");
            Console.ReadLine();
            serviceHost.Close();
        }
        Uri baseAddress = new Uri("net.tcp://localhost:8014/TestService.svc");         
    }
}

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    string GetData(string data);
}

public class TestService: ITestService
{
    public string GetData(string data)
    {
        Console.WriteLine(data);
        Thread.Sleep(5000);
        return "Ok";
    }
}

Конфигурационная часть:

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="basicHttpBinding" closeTimeout="00:02:00" openTimeout="00:02:00"
      receiveTimeout="00:02:00" sendTimeout="00:02:00" maxBufferSize="2000000000"
      maxReceivedMessageSize="2000000000" />
  </basicHttpBinding>
  <netTcpBinding>
    <binding name="netTcpBinding" closeTimeout="00:02:00" openTimeout="00:02:00"
      receiveTimeout="00:02:00" sendTimeout="00:02:00" listenBacklog="2000"
      maxBufferSize="2000000000" maxConnections="1000" maxReceivedMessageSize="2000000000">
      <security mode="None">
        <transport protectionLevel="EncryptAndSign" />
      </security>
    </binding>
    <binding name="TestServiceTcpEndPoint">
      <security mode="None" />
    </binding>
  </netTcpBinding>      
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="CommonServiceBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" maxConcurrentInstances="1000" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<services>
  <service name="ServiceLauncher.TestService" behaviorConfiguration="CommonServiceBehavior">
    <endpoint address="" binding="netTcpBinding" bindingConfiguration="netTcpBinding" name="TestServiceTcpEndPoint" contract="ServiceLauncher.ITestService" />
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding" name="TestServiceTcpEndPoint" contract="ServiceLauncher.ITestService" />
    <endpoint address="mex"  binding="mexHttpBinding" bindingName="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8014/TestService.svc"/>
        <add baseAddress="http://localhost:1234/TestService.svc"/>
      </baseAddresses>
    </host>
  </service>
</services>
</system.serviceModel>

И у меня есть клиент, который использует этот сервис во многих потоках с созданием нового экземпляра для каждого потока (это требование):

    static void Main(string[] args)
    {           
        for (int i = 0; i < 1000; i++)
        {
            Thread tr = new Thread(() =>
            {
                using (var service = new Test.TestServiceClient())
                {
                    var result = service.GetData(i.ToString());
                    Console.WriteLine(string.Format("{0}: {1} {2}",
                                      DateTime.Now,
                                      result,
                                      Thread.CurrentThread.ManagedThreadId));
                }  
            });
            tr.Start();                
        }
        Console.ReadLine();       
    }

В этом случае после некоторых запросов клиент вызывает EndpointNotFoundException, код ошибки TCP 10061, Соединение не может быть установлено, поскольку целевой компьютер активно отказал ему. Количество запросов все время различно, и это не серверная часть, потому что она все еще работает в нормальном состоянии. И я вижу, что он продолжает получать запросы, что является самым странным в этой ситуации. Что также странно, что это может сделать ваш клиентский хост "бессмертным" после исключения - так что вы не сможете уничтожить его любым способом, кроме перезагрузки системы. Я почти уверен, что проблема в низком уровне сокета клиента, и это как-то связано с таким большим количеством потоков, но мне не удалось найти что-то, что могло бы объяснить проблему.

2 ответа

Каждый раз, когда я видел ошибку "Невозможно установить соединение, потому что целевая машина активно отказывала". проблема не была с сервисом. Обычно проблема заключается в достижении сервиса.

Пара предложений:

  1. избежать using с прокси WCF. Вы можете выбрать один из нескольких разумных решений.

  2. Прочитайте мой ответ о производительности, задержке и масштабируемости WCF. Помимо запуска потоков по старинке, это в основном то же тестовое приложение. В этом посте описываются все клиентские причины (которые я смог найти), которые вызывают "Невозможно установить соединение, поскольку целевая машина активно отказывала в этом", а также различные настройки WCF, TCP и пула потоков, которые можно настроить.

Вы можете использовать внутренние ограничения для одновременных соединений TCP/IP в Windows. Посмотрите на эту статью и посмотрите, поможет ли это:

http://smallvoid.com/article/winnt-tcpip-max-limit.html

Другие вопросы по тегам