nServiceBus经销商挂起

时间:2014-02-18 12:29:50

标签: garbage-collection msmq nservicebus windbg

当运行经常与5位以上工作人员忙碌的经销商时,服务会停止处理消息。

NServiceBus版本是3.3.8,其中有一些来自4.x的修补程序(关于MessagePropertyFilters,关于ClearAvailabilityForWorkers的锁定以及一些小问题)源代码可在此处获得:

https://github.com/PeterLehmann/NServiceBus/tree/undoWfpNameChange

使用WinDBG分析挂起的服务显示大多数线程正在等待内存分配或释放,如下所示:

System.Runtime.InteropServices.GCHandle.InternalFree(IntPtr)
System.Runtime.InteropServices.GCHandle.Free()
System.Messaging.Interop.MessagePropertyVariants.Unlock()
System.Messaging.MessageQueue.ReceiveCurrent(System.TimeSpan, Int32, System.Messaging.Interop.CursorHandle, System.Messaging.MessagePropertyFilter, System.Messaging.MessageQueueTransaction, System.Messaging.MessageQueueTransactionType)
System.Messaging.MessageQueue.Peek(System.TimeSpan)
NServiceBus.Unicast.Queuing.Msmq.MsmqMessageReceiver.HasMessage()
NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.HasMessage()
NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.Process()
NServiceBus.Utils.WorkerThread.Loop()
System.Threading.ExecutionContext.runTryCode(System.Object)

System.Runtime.InteropServices.GCHandle.InternalAlloc(System.Object, System.Runtime.InteropServices.GCHandleType)
System.Runtime.InteropServices.GCHandle..ctor(System.Object, System.Runtime.InteropServices.GCHandleType)
System.Messaging.Interop.MessagePropertyVariants.Lock()
System.Messaging.MessageQueue.ReceiveCurrent(System.TimeSpan, Int32, System.Messaging.Interop.CursorHandle, System.Messaging.MessagePropertyFilter, System.Messaging.MessageQueueTransaction, System.Messaging.MessageQueueTransactionType)
System.Messaging.MessageQueue.Peek(System.TimeSpan)
NServiceBus.Unicast.Queuing.Msmq.MsmqMessageReceiver.HasMessage()
NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.HasMessage()
NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.Process()
NServiceBus.Utils.WorkerThread.Loop()
System.Threading.ExecutionContext.runTryCode(System.Object)

我们有多个线程,上面两个堆栈似乎都挂起,消息没有被处理。然后我们有单线程也在等待Raven通信中间的InternalAlloc

System.Runtime.InteropServices.GCHandle.InternalAlloc(System.Object, System.Runtime.InteropServices.GCHandleType)
System.Runtime.InteropServices.GCHandle..ctor(System.Object, System.Runtime.InteropServices.GCHandleType)
System.Net.SafeDeleteContext.InitializeSecurityContext(System.Net.SecurDll, System.Net.SafeFreeCredentials ByRef, System.Net.SafeDeleteContext ByRef, System.String, System.Net.ContextFlags, System.Net.Endianness, System.Net.SecurityBuffer, System.Net.SecurityBuffer[], System.Net.SecurityBuffer, System.Net.ContextFlags ByRef)
System.Net.SSPIAuthType.InitializeSecurityContext(System.Net.SafeFreeCredentials, System.Net.SafeDeleteContext ByRef, System.String, System.Net.ContextFlags, System.Net.Endianness, System.Net.SecurityBuffer[], System.Net.SecurityBuffer, System.Net.ContextFlags ByRef)
System.Net.SSPIWrapper.InitializeSecurityContext(System.Net.SSPIInterface, System.Net.SafeFreeCredentials, System.Net.SafeDeleteContext ByRef, System.String, System.Net.ContextFlags, System.Net.Endianness, System.Net.SecurityBuffer[], System.Net.SecurityBuffer, System.Net.ContextFlags ByRef)
System.Net.NTAuthentication.GetOutgoingBlob(Byte[], Boolean, System.Net.SecurityStatus ByRef)
System.Net.NTAuthentication.GetOutgoingBlob(System.String)
System.Net.NegotiateClient.DoAuthenticate(System.String, System.Net.WebRequest, System.Net.ICredentials, Boolean)
System.Net.NegotiateClient.Authenticate(System.String, System.Net.WebRequest, System.Net.ICredentials)
System.Net.AuthenticationManager.Authenticate(System.String, System.Net.WebRequest, System.Net.ICredentials)
System.Net.AuthenticationState.AttemptAuthenticate(System.Net.HttpWebRequest, System.Net.ICredentials)
System.Net.HttpWebRequest.CheckResubmitForAuth()
System.Net.HttpWebRequest.CheckResubmit(System.Exception ByRef)
System.Net.HttpWebRequest.DoSubmitRequestProcessing(System.Exception ByRef)
System.Net.HttpWebRequest.ProcessResponse()
System.Net.HttpWebRequest.SetResponse(System.Net.CoreResponseData)
System.Net.ConnectStream.ProcessWriteCallDone(System.Net.ConnectionReturnResult)
System.Net.ConnectStream.CallDone(System.Net.ConnectionReturnResult)
System.Net.ConnectStream.WriteHeaders(Boolean)
System.Net.HttpWebRequest.EndSubmitRequest()
System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest, Boolean)
System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest, System.String)
System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint)
System.Net.HttpWebRequest.GetResponse()
Raven.Client.Connection.HttpJsonRequest.ReadStringInternal(System.Func`1<System.Net.WebResponse>)
Raven.Client.Connection.HttpJsonRequest.ReadResponseString()
Raven.Client.Connection.HttpJsonRequest.ReadResponseJson()
Raven.Client.Connection.ServerClient.DirectCommit(System.Guid, System.String)
Raven.Client.Connection.ServerClient+<>c__DisplayClass5b.<Commit>b__5a(System.String)
Raven.Client.Connection.ServerClient.TryOperation[[System.__Canon, mscorlib]](System.Func`2<System.String,System.__Canon>, System.String, Boolean, System.__Canon ByRef)
Raven.Client.Connection.ServerClient.ExecuteWithReplication[[System.__Canon, mscorlib]](System.String, System.Func`2<System.String,System.__Canon>)
Raven.Client.Connection.ServerClient.Commit(System.Guid)
Raven.Client.Document.DocumentSession.Commit(System.Guid)
Raven.Client.Document.RavenClientEnlistment.Commit(System.Transactions.Enlistment)
System.Transactions.Oletx.OletxEnlistment.CommitRequest()
...

我们尝试过Concurrent和Servermode垃圾收集的变体,看起来垃圾收集正在发生时会发生问题,但有时候,我们看到GC运行完美且正常吞吐量不受影响。

我检查了是否有东西阻塞了终结器,但似乎并非如此,做了一些挖掘以找出memoryallocation / deallocation中的某些东西是否会死锁但似乎无法找到任何东西(我可以在这里深入挖掘,但首先想要一些输入。)

当发生这种情况时,操作正在重新启动服务,但即使这种情况有时也会失败,服务有时会陷入“停止”状态并且必须被杀死才能让他们再次开始处理。

有没有其他人使用nServiceBus 3.3.8经历过挂起服务?

1 个答案:

答案 0 :(得分:1)

因此,为了回答我自己的问题,我们在升级到.NET 4.5.1之后在系统上运行.NET 4.0.30319,上述问题似乎已经消失。

我怀疑已经有一些关于内存处理和垃圾收集的更新已经解决了这个问题。