Nservicebus 如果某个服务因某种原因出错,编排传奇应该如何表现

Nservicebus 如果某个服务因某种原因出错,编排传奇应该如何表现,nservicebus,Nservicebus,我想弄明白这件事已经有一段时间了,但就是想不起来 当请求服务-a(也使用具有主要和延迟重试的nservicebus实现)时,服务a由于暂时/半暂时错误而失败,服务将重试,直到所有重试都已完成,消息被发送到错误队列(假设我们使用的是ASB或rabbitmq或可能是msmq),在服务a的响应决定了saga是向服务B还是C发出请求的情况下,saga应该如何表现。 或者,如果saga在设置的时间内没有收到预期的响应,那么它应该超时,然后继续为service-A之前执行的任何其他服务发出补偿请求(如果需要

我想弄明白这件事已经有一段时间了,但就是想不起来

当请求服务-a(也使用具有主要和延迟重试的nservicebus实现)时,服务a由于暂时/半暂时错误而失败,服务将重试,直到所有重试都已完成,消息被发送到错误队列(假设我们使用的是ASB或rabbitmq或可能是msmq),在服务a的响应决定了saga是向服务B还是C发出请求的情况下,saga应该如何表现。
或者,如果saga在设置的时间内没有收到预期的响应,那么它应该超时,然后继续为service-A之前执行的任何其他服务发出补偿请求(如果需要补偿的话)。。或者我应该在每个服务中实现自定义错误处理来处理瞬时/半瞬时错误,并让saga知道是否发生了故障(如果是这样的话..我如何使用默认的nservicebus重试)…请建议

来自服务的回复将是最后一步,这意味着所有其他步骤(可能导致失败)都已通过。如果/一旦编排saga收到回复消息,它就知道服务已经执行了它的工作

在这部传奇中,你有:

public class MySaga : IAmStartedBy<SagaStart>, IHandleMessage<OperationPerformed>
{
    //You'll need to map/store some sort of a ID to know the replies
    //that come back are related to which saga instance

    public Task Handle(SagaStart startMessage, IMessageContext context) 
    {
        await context.Send(new PerformOperation() 
        {
           OperationId = startMessage.Id
        });
    }

    public Task Handle(OperationPerformed message, IMessageContext context) 
    {
        //Operation has succeeded.
        //Maybe saga is finished at this point?
        MarkAsComplete();
        return Task.CompletedTask;
    }
}

public class OperationService : IHandleMessages<PerformOperation>
{
    public async Task Handle(OperationPerformed message, IMessageContext context)
    {
        //call external service
        await httpClient.PerformNetworkBoundCall(); // <- Could fail

        await context.Reply(new OperationPerformed()
        {
            OperationId = message.OperationId
        });
    }
}
公共类MySaga:IAmStartedBy,IHandleMessage
{
//您需要映射/存储某种ID才能知道回复
//这一切都与哪一个传奇故事有关
公共任务句柄(SagaStartMessage、IMessageContext上下文)
{
wait context.Send(新性能操作()
{
OperationId=startMessage.Id
});
}
公共任务句柄(OperationPerformed消息,IMessageContext上下文)
{
//行动成功。
//也许这部传奇故事就此结束了?
MarkAsComplete();
返回Task.CompletedTask;
}
}
公共类操作服务:IHandleMessages
{
公共异步任务句柄(OperationPerformed消息,IMessageContext上下文)
{
//呼叫外部服务

等待httpClient.PerformNetworkBoundCall();//您好,如果httpClient.PerformNetworkBoundCall()不断失败操作服务不断重试,消息被推送到错误队列。因此,服务将永远无法回复此事件。这正是问题所在!如果服务调用是“暂时的”,它最终将成功。如果是由于错误,则需要修复此问题,部署并重试消息以成功。在bo中在这种情况下,只有成功调用服务后,业务场景才会完成。您还可以使用超时机制作为“补偿”,例如,如果saga流程未在x分钟内完成,则向用户发送通知(或任何有意义的通知).Hi Hadi,谢谢你的回答。将使用额外的超时选项设置超时,以便在db故障无法恢复时发出补偿请求(错误的最坏情况应该是暂时的)。干杯。