Поток потока при связывании 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 ответа
Каждый раз, когда я видел ошибку "Невозможно установить соединение, потому что целевая машина активно отказывала". проблема не была с сервисом. Обычно проблема заключается в достижении сервиса.
Пара предложений:
избежать
using
с прокси WCF. Вы можете выбрать один из нескольких разумных решений.Прочитайте мой ответ о производительности, задержке и масштабируемости WCF. Помимо запуска потоков по старинке, это в основном то же тестовое приложение. В этом посте описываются все клиентские причины (которые я смог найти), которые вызывают "Невозможно установить соединение, поскольку целевая машина активно отказывала в этом", а также различные настройки WCF, TCP и пула потоков, которые можно настроить.
Вы можете использовать внутренние ограничения для одновременных соединений TCP/IP в Windows. Посмотрите на эту статью и посмотрите, поможет ли это: