2015-06-11 2 views
2

Я работаю над службой WCF, размещенной в службе Windows, используя nettcpbinding.WCF не обрабатывает 1000 вызовов в секунду

Когда я пытался выполнить нагрузочный тест в сервисе, я построил простой клиент, который вызывает услугу около 1000 вызовов во второй, возврат из службы занимает примерно от 2 до 8 секунд и после выхода из простого клиента, запускаемого для около получаса время, чтобы вернуть результат, увеличивается, и некоторый клиент дает некоторые временные исключения для времени отправки, которое было настроено на 2 минуты.

я пересмотрел throltting конфигурации службы, и это, как этот

этих шагов я пытался выполнить:

  1. пересмотрел конфигурацию службы дроссельного

    <serviceThrottling maxConcurrentCalls="2147483647" maxConcurrentInstances="2147483647" maxConcurrentSessions="2147483647"/>

  2. работает на машине Windows 7, поэтому я перешел на сервер 2008, но тот же результат.
  3. обновить конфигурацию привязки tcp, как показано ниже: NetTcpBinding baseBinding = новый NetTcpBinding (SecurityMode.None, true); baseBinding.MaxBufferSize = int.MaxValue;

     baseBinding.MaxConnections = int.MaxValue; 
         baseBinding.ListenBacklog = int.MaxValue; 
         baseBinding.MaxBufferPoolSize = long.MaxValue; 
    
         baseBinding.TransferMode = TransferMode.Buffered; 
         baseBinding.MaxReceivedMessageSize = int.MaxValue; 
         baseBinding.PortSharingEnabled = true; 
         baseBinding.ReaderQuotas.MaxDepth = int.MaxValue; 
         baseBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue; 
         baseBinding.ReaderQuotas.MaxArrayLength = int.MaxValue; 
         baseBinding.ReaderQuotas.MaxBytesPerRead = int.MaxValue; 
         baseBinding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue; 
         baseBinding.ReliableSession.Enabled = true; 
         baseBinding.ReliableSession.Ordered = true; 
         baseBinding.ReliableSession.InactivityTimeout = new TimeSpan(23, 23, 59, 59); 
    
    
         BindingElementCollection elements = baseBinding.CreateBindingElements(); 
         ReliableSessionBindingElement reliableSessionElement = elements.Find<ReliableSessionBindingElement>(); 
         if (reliableSessionElement != null) 
         { 
          reliableSessionElement.MaxPendingChannels = 128; 
    
    
    
          TcpTransportBindingElement transport = elements.Find<TcpTransportBindingElement>(); 
    
          transport.ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint = 1000; 
    
          CustomBinding newBinding = new CustomBinding(elements);      
          newBinding.CloseTimeout = new TimeSpan(0,20,9); 
          newBinding.OpenTimeout = new TimeSpan(0,25,0); 
          newBinding.ReceiveTimeout = new TimeSpan(23,23,59,59); 
          newBinding.SendTimeout = new TimeSpan(0,20,0); 
          newBinding.Name = "netTcpServiceBinding"; 
    
          return newBinding; 
         } 
         else 
         { 
          throw new Exception("the base binding does not " + 
           "have ReliableSessionBindingElement"); 
         } 
    
  4. изменил мою функцию службы использовать асинхра и ждет

    public async Task<ReturnObj> Connect(ClientInfo clientInfo) 
    { 
        var task = Task.Factory.StartNew(() => 
        { 
         // do the needed work 
         // insert into database 
         // query some table to return information to client 
        }); 
    
    
        var res = await task; 
        return res; 
    } 
    

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

  5. применил решение нити Worker, предложенный в этой связи https://support.microsoft.com/en-us/kb/2538826 хотя я использую .net 4.5.1 и установить MinThreads 1000 работника и 1000 IOCP

после всего этого начала службы для обработки больше запросов, но задержка по-прежнему существует, и простой клиент занимает около 4 часов, чтобы дать время

странное, что я нашел служебный дескриптор от 8 до 16 вызовов в пределах 100 мс, относительно количества потоков, в настоящее время живущих в обслуживание.

Я нашел много статей, посвященных настройке, которые необходимо поместить в machine.config и Aspnet.config, я думаю, что это не связано с моим делом, поскольку я использую nettcp для службы Windows, а не для IIS, но я реализовал эти изменения и не обнаружили изменений в результатах.

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

+2

Если метод не может работать в течение 1/1000 секунды, вы никогда не сможете предотвратить таймаут. вы продолжаете кормить данные службы и не можете обрабатывать ее быстрее, чем вы ее кормите. в конце концов, воронка будет полной, а остатки не удастся. – Franck

+1

Если вам нужно обслуживать 1000 запросов в секунду, вы можете начать изучать системы балансировки нагрузки/распределения нагрузки. –

+0

Да, ему нужно что-то вроде лазурного с множеством узлов. Ему нужна настройка, которая может подключаться к базе данных, делать вставки, данные запроса, строить объект и возвращать пользователю все, что в 1/1000-й секунде или лучше, чтобы не откладывать сверхурочные соединения. У меня есть балансировка SQL-сервера Killer, и я не могу получить больше 4 мс, ему нужно 4 раза быстрее. – Franck

ответ

0

Это, скорее всего, связано с тем, что режим параллелизма установлен на Single (это значение по умолчанию). Попробуйте установить ConcurrencyMode в Multiple, добавив ServiceBehaviourAttribute в вашу реализацию службы.

Обязательно проверьте documenttation: https://msdn.microsoft.com/en-us/library/system.servicemodel.concurrencymode(v=vs.110).aspx

Пример:

// With ConcurrencyMode.Multiple, threads can call an operation at any time. 
// It is your responsibility to guard your state with locks. If 
// you always guarantee you leave state consistent when you leave 
// the lock, you can assume it is valid when you enter the lock. 

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
class MultipleCachingHttpFetcher : IContract 

Вы можете быть заинтересованы также в Sessions, Instancing, and Concurrency статье, которая описывает проблемы параллелизма.

+0

У меня уже установлено несколько, это моя текущая конфигурация [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] – user1747513

1

Это может быть как ваш тестовый клиент написан. С NetTcp, когда вы создаете канал, он пытается получить один из пула пустых соединений. Если он пуст, он открывает новое соединение сокета. Когда вы закрываете клиентский канал, он возвращается обратно в пул пустых соединений. Размер по умолчанию пула пустых соединений равен 10, что означает, что после того, как в пуле ожидания будет 10 соединений, любые последующие закрытия фактически закрывают TCP-сокет. Если ваш тестовый код быстро создает и удаляет каналы, вы можете отказаться от соединений в пуле. Тогда вы можете столкнуться с проблемой слишком большого количества сокетов в состоянии TIME_WAIT.
Here - это сообщение в блоге о том, как изменить поведение пула.

Смежные вопросы