我使用AutoFac为2个消费者设置了一个Windows服务。在一条快乐的道路上,这非常有效。我对MassTransit为我处理异常的行为表示不满。 正如文档所述: http://docs.masstransit-project.com/en/latest/overview/errors.html
最简单的方法是让异常泡沫消失 消费者方法和MassTransit将自动捕获异常 为你
当消费者抛出异常时,MassTransit确实会产生错误,但我的服务仍然崩溃:
应用程序:WerkgeverService.exe Framework版本:v4.0.30319 描述:由于未处理的异常,进程终止。 异常信息:AutoMapper.AutoMapperMappingException Stack:at System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__5(System.Object的) 在 System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object的) 在 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback,System.Object,Boolean)at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback,System.Object,Boolean)at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 在System.Threading.ThreadPoolWorkQueue.Dispatch()at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
记录异常,因为我记录了所有未捕获的异常:
Protected Overrides Sub OnStart(args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
Try
Initialize()
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf HandleBubbledException
Catch ex As Exception
Me.EventLog.WriteEntry(ex.Message, EventLogEntryType.Error)
Throw
End Try
End Sub
Private Sub HandleBubbledException(sender As Object, args As UnhandledExceptionEventArgs)
Dim exception = DirectCast(args.ExceptionObject, Exception)
Me.EventLog.WriteEntry(String.Format("Message: {0} {2}Stacktrace:{2}{1}", exception.Message, exception.StackTrace, Environment.NewLine), EventLogEntryType.Error)
End Sub
异常本身就是来自AutoMapper的异常,并且确实记录在事件日志中(因此它不由MassTransit处理):
Message: Missing type map configuration or unsupported mapping.
Mapping types:
Int32 -> Int64
System.Int32 -> System.Int64
问题:有什么方法可以防止服务崩溃而不向每个消费者添加try/catch
? AFAIK MassTransit应该处理这些......
答案 0 :(得分:2)
这可能与我的情况有关,但我认为我发现了问题(感谢MassTransit的人)。
问题是我的消费者启动了一个新线程。
Public Sub Consume(message As IConsumeContext(Of IMessage)) Implements Consumes(Of IConsumeContext(Of IMessage)).All.Consume
HandleMessageAsync(message)
End Sub
Private Async Sub HandleMessageAsync(context As IConsumeContext(Of IMessage))
Dim something = Await _controller.GetSomething(context.Message)
Dim response As New MessageResponse
response.something = something
context.Respond(response)
End Sub
这个线程不受MassTransit的控制,因此无法从该线程中捕获任何异常。我的解决方案是将其更改为:
Public Sub Consume(context As IConsumeContext(Of IMessage)) Implements Consumes(Of IConsumeContext(Of IMessage)).All.Consume
Dim something = _controller.GetSomething(context.Message).Result
Dim response As New MessageResponse
response.something = something
context.Respond(response)
End Sub
确保在Consume方法退出之前异常冒泡。否则你必须亲自抓住它。