У меня есть клиент-серверное приложение. Мой сценарий:
- .Net Framework 4.6.1
- Quad Core i7 с поддержкой гиперпоточности
- загрузка ЦП сервера от 20 до 70%
- Загрузка сети <5% (сетевой адаптер GBit) </li>
- 100 пользователей
- 30 служб (некоторые административные, некоторые общие для каждого типа данных) работают, и каждый пользователь подключен ко всем службам
- NetTcpBinding (сжатие включено)
- ReliableSession включен
- каждую секунду я запускаю (на стороне сервера) уведомление об обновлении, и все клиенты загружаются с сервера прибл. 100 кБ
- дополнительно работает сердцебиение (для проверки интервала 15 секунд), которое просто возвращает время сервера в UTC
Иногда соединения WCF переходят в состояние отказа. Обычно, когда это происходит, сервер вообще не имеет восходящей сети. Я написал дамп памяти и смог увидеть, что множество потоков WCF ожидали каких-то WaitQueue
. Стек вызовов:
Server stack trace:
at System.ServiceModel.Channels.TransmissionStrategy.WaitQueueAdder.Wait(TimeSpan timeout)
at System.ServiceModel.Channels.TransmissionStrategy.InternalAdd(Message message, Boolean isLast, TimeSpan timeout, Object state, MessageAttemptInfo& attemptInfo)
at System.ServiceModel.Channels.ReliableOutputConnection.InternalAddMessage(Message message, TimeSpan timeout, Object state, Boolean isLast)
at System.ServiceModel.Channels.ReliableDuplexSessionChannel.OnSend(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.DuplexChannel.Send(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.DuplexChannelBinder.Send(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Я настроил настройки, и, похоже, ситуация улучшилась - теперь клиентов стало меньше. Мои настройки:
- ReliableSession.InactivityTimeout: 01: 30: 00
- ReliableSession.Enabled: True
- ReliableSession.Ordered: False
- ReliableSession.FlowControlEnabled: False
- ReliableSession.MaxTransferWindowSize: 4096
- ReliableSession.MaxPendingChannels: 16384
- MaxReceivedMessageSize: 1073741824
- ReaderQuotas.MaxStringContentLength: 8388608
- ReaderQuotas.MaxArrayLength: 1073741824
Я застрял. Почему все звонки пытаются ждать WaitQueue
в TransmissionStrategy
? Меня не волнуют сообщения, отправленные не по порядку (я сам об этом позабочусь). Я уже думал об отключении надежного обмена сообщениями, но приложение используется в сети компании по всему миру. Мне нужно знать, что мои сообщения были доставлены.
Есть идеи, как научить WCF просто отправлять сообщения и больше ни о чем не беспокоиться?
EDIT
Значения для регулирования работы установлены на Int32.MaxValue
.
Я также пытался установить MaxConnections
и ListenBackLog
(на NetTcpBinding
) на их максимальные значения. Это ничего не изменило - насколько я могу судить.
РЕДАКТИРОВАТЬ 2
Проверка трассировок WCF говорит мне (немецкое сообщение, следовательно, грубый перевод), что в окне надежной передачи сообщений нет свободного места - и тогда все, что я получаю, это тайм-ауты, потому что больше сообщений не отправляется.
Что там происходит? Возможно ли, что надежный обмен сообщениями смущает себя?