Поток сообщений DebugDiag не кажется ожидающим ответа на удаленном сервере
У нас есть служба C# Windows, которая запускает процесс, который разбит на несколько задач. Большинство задач связываются с веб-сервисом, использующим WCF для выполнения работы с базой данных. Задачи службы выполняются в несколько потоков.
Клиент обратился к нам со службой поддержки, сказав, что служба Windows иногда не отвечает и требует перезапуска. Я получил дамп памяти из службы Windows. Я запустил DebugDiag 2.0 для анализа файла дампа.
В отчете DebugDiag есть интересная запись в резюме:
Следующие потоки в WindowsService.DMP пытаются создать запрос HttpWebRequest, однако они не ожидают ответа на удаленном сервере (например, не "на проводе"). Один или несколько из этих запросов используют как минимум половину своего максимального числа доступных соединений.
(17 18 27 31 32 33 42) 12,07% заблокированных тем (7 потоков)
Если многие потоки находятся в этом состоянии, это часто указывает на то, что предел регулирования (т. Е. Настройка "maxconnection") был исчерпан. Нажмите на любой поток в списке слева, чтобы просмотреть подробности регулирования для веб-запроса, который он ожидает.
При необходимости вы можете увеличить количество доступных подключений, изменив параметр maxconnection в файле конфигурации приложения (см.
<connectionManagement>
Элемент), или путем программного изменения соответствующего свойства ConnectionLimit (см. Управление соединениями).
Я перешел к теме 17 и увидел это:
Поток 17 - Системный идентификатор 4612
Точка входа mscorwks!Thread:: middleThreadProc Время создания 10.10.2015 10:13:14 Время, проведенное в режиме пользователя 0 Дней 00:00:00.000 Время, проведенное в режиме ядра 0 Дней 00:00:00.000
Этот поток пытается создать запрос HttpWebRequest, однако, похоже, что он не ожидает ответа от удаленного сервера (например, не "в сети"). Один или несколько из этих запросов используют как минимум половину своего максимального числа доступных соединений.
Предупреждение: используется не менее половины доступных соединений
HttpRequest URI:
http://WebServer/MyWebSite/SubDir/MyService.svc
ServicePoint - ConnectionLimit: 48 CurrentConnections: 44Объект HttpWebRequest является адресом обратной связи, но ограничение подключения все еще применяется к этому объекту веб-запроса, потому что ограничение подключения определено (либо через autoconfig, установленный в true в разделе processModel, либо путем добавления записи * в разделе connectionManagement
Стек вызовов.NET ниже:
Function
[[HelperMethodFrame_1OBJ] (System.Threading.WaitHandle.WaitOneNative)] System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)
mscorlib_ni!System.Threading.WaitHandle.WaitOne(Int64, Boolean)+2f
mscorlib_ni!System.Threading.WaitHandle.WaitOne(Int32, Boolean)+25
System_ni!System.Net.LazyAsyncResult.WaitForCompletion(Boolean)+d3
System_ni!System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest)+2b7
System_ni!System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest, System.String)+7c
System_ni!System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint)+f9
System_ni!System.Net.HttpWebRequest.GetRequestStream(System.Net.TransportContext ByRef)+1d3
System_ni!System.Net.HttpWebRequest.GetRequestStream()+e
System_ServiceModel_ni!System.ServiceModel.Channels.HttpOutput+WebRequestHttpOutput.GetOutputStream()+45
System_ServiceModel_ni!System.ServiceModel.Channels.HttpOutput.Send(System.TimeSpan)+f6
System_ServiceModel_ni!System.ServiceModel.Channels.HttpChannelFactory+HttpRequestChannel+HttpChannelRequest.SendRequest(System.ServiceModel.Channels.Message, System.TimeSpan)+121
System_ServiceModel_ni!System.ServiceModel.Channels.RequestChannel.Request(System.ServiceModel.Channels.Message, System.TimeSpan)+cb
System_ServiceModel_ni!System.ServiceModel.Dispatcher.RequestChannelBinder.Request(System.ServiceModel.Channels.Message, System.TimeSpan)+17
System_ServiceModel_ni!System.ServiceModel.Channels.ServiceChannel.Call(System.String, Boolean, System.ServiceModel.Dispatcher.ProxyOperationRuntime, System.Object[], System.Object[], System.TimeSpan)+1a2
System_ServiceModel_ni!System.ServiceModel.Channels.ServiceChannel.Call(System.String, Boolean, System.ServiceModel.Dispatcher.ProxyOperationRuntime, System.Object[], System.Object[])+33
System_ServiceModel_ni!System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(System.Runtime.Remoting.Messaging.IMethodCallMessage, System.ServiceModel.Dispatcher.ProxyOperationRuntime)+43
System_ServiceModel_ni!System.ServiceModel.Channels.ServiceChannelProxy.Invoke(System.Runtime.Remoting.Messaging.IMessage)+65
mscorlib_ni!System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(System.Runtime.Remoting.Proxies.MessageData ByRef, Int32)+bd
[[TPMethodFrame] (IMyWebService.GetDataSet)]
IMyWebService.GetDataSet(System.Guid, System.String, System.Data.DataSet)
<service code snipped>
mscorlib_ni!System.Threading.ThreadHelper.ThreadStart_Context(System.Object)+66
mscorlib_ni!System.Threading.ExecutionContext.runTryCode(System.Object)+51
[[HelperMethodFrame_PROTECTOBJ] (System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup)]
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)
mscorlib_ni!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+67
mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+45
mscorlib_ni!System.Threading.ThreadHelper.ThreadStart()+44
[[GCFrame]]
Я вижу рекомендации, которые он сделал, и начал их изучать. Мой вопрос:
Почему DebugDiag говорит, что поток не ожидает ответа от сервера?
Глядя на .NET Reference Source, кажется, что запрос был успешно отправлен, и служба, похоже, ожидает ответа.
ОБНОВИТЬ
Прерываясь в обычный вызов, я вижу стек вызовов, ожидающий в ws2_2, как предложено Puneet Gupta ниже:
ntdll.dll!_NtWaitForSingleObject@12()
mswsock.dll!_SockWaitForSingleObject@16()
mswsock.dll!_WSPRecv@36()
***ws2_32.dll!_recv@16()***
System.ni.dll!6c084a13()
[Managed to Native Transition]
System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode)
System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags)
System.dll!System.Net.Sockets.NetworkStream.Read(byte[] buffer, int offset, int size)
System.dll!System.Net.PooledStream.Read(byte[] buffer, int offset, int size)
System.dll!System.Net.Connection.SyncRead(System.Net.HttpWebRequest request, bool userRetrievedStream, bool probeRead)
System.dll!System.Net.ConnectStream.ProcessWriteCallDone(System.Net.ConnectionReturnResult returnResult)
System.dll!System.Net.HttpWebRequest.WriteCallDone(System.Net.ConnectStream stream, System.Net.ConnectionReturnResult returnResult)
System.dll!System.Net.ConnectStream.CallDone(System.Net.ConnectionReturnResult returnResult)
System.dll!System.Net.ConnectStream.ResubmitWrite(System.Net.ConnectStream oldStream, bool suppressWrite)
System.dll!System.Net.HttpWebRequest.EndWriteHeaders_Part2()
System.dll!System.Net.HttpWebRequest.EndWriteHeaders(bool async)
System.dll!System.Net.HttpWebRequest.WriteHeadersCallback(System.Net.WebExceptionStatus errorStatus, System.Net.ConnectStream stream, bool async)
System.dll!System.Net.ConnectStream.WriteHeaders(bool async)
System.dll!System.Net.HttpWebRequest.EndSubmitRequest()
System.dll!System.Net.HttpWebRequest.CheckDeferredCallDone(System.Net.ConnectStream stream)
System.dll!System.Net.HttpWebRequest.GetResponse()
System.ServiceModel.dll!System.ServiceModel.Channels.HttpChannelFactory<System.ServiceModel.Channels.IRequestChannel>.HttpRequestChannel.HttpChannelRequest.WaitForReply(System.TimeSpan timeout)
System.ServiceModel.dll!System.ServiceModel.Channels.RequestChannel.Request(System.ServiceModel.Channels.Message message, System.TimeSpan timeout)
System.ServiceModel.dll!System.ServiceModel.Dispatcher.RequestChannelBinder.Request(System.ServiceModel.Channels.Message message, System.TimeSpan timeout) Unknown
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.Call(string action, bool oneway, System.ServiceModel.Dispatcher.ProxyOperationRuntime operation, object[] ins, object[] outs, System.TimeSpan timeout)
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(System.Runtime.Remoting.Messaging.IMethodCallMessage methodCall, System.ServiceModel.Dispatcher.ProxyOperationRuntime operation)
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.Invoke(System.Runtime.Remoting.Messaging.IMessage message)
mscorlib.dll!System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(ref System.Runtime.Remoting.Proxies.MessageData msgData, int type)
Поэтому обычно он будет ждать ответа от сокета Windows. В этом случае потоки, вероятно, ожидают подключения, чтобы стать доступными для обработки запроса - как показано в других сообщениях DebugDiag.
2 ответа
Причина, по которой в сообщении говорится, что он, кажется, не ожидает в сети, заключается в том, что последний кадр в потоке - это waithandle.waitone.
Для потока, который действительно ожидает соединения, мы должны увидеть ws2_32 (в собственном стеке), который представляет собой библиотеку сокетов Windows или некоторые функции из system.net.sockets в управляемом стеке.
Удалось ли вам захватить несколько дампов? Если да, вы видели, что состояние потока изменилось в одном дампе по сравнению со вторым?
Показывает ли! Dso (!DumpStackObjects) какой-либо объект подключения в текущем потоке? Если это так, каково значение m_WaitList в объекте System.Net.Connection и каково значение m_CurrentRequest? Поскольку ваш callstack НЕ показывает, что мы ожидаем ws2_32 (WinSock), это указывает на то, что HWR все еще ожидает получения доступного соединения или сокета.