nservicebus sagas - 试图了解目的和利益

时间:2018-04-05 20:03:49

标签: nservicebus nservicebus-sagas

我已多次阅读网站上的文档。我一遍又一遍地阅读相同的文章,我无法理解他们想要用传奇来实现的目标。此外,互联网上几乎没有与此主题相关的资源。

但我完全陷入困境,试图理解定义所谓的传奇的目的和好处。我理解处理程序(IHandleMessages) - 这些是拦截器。但我无法理解佐贺的用途。文档中的语言假设我应该知道一些特别的东西来掌握这个想法,但我不这样做。

有人可以用简单的语言向我解释,希望以现实生活中的例子说明我必须或应该定义Saga的情况,这样做有什么好处?我创建了一个具有多个端点和Saga定义的应用程序,如示例中所示,它可以工作(我猜)但我不明白这些传奇是如何定义的......在许多示例中,他们在Saga中使用RequestTimeout()方法类。为什么,为什么有人想故意造成超时?我不想在这里放任何代码片段,因为它不相关,我需要理解为什么我要使用" Sagas"这意味着什么?

谢谢。

1 个答案:

答案 0 :(得分:7)

NServiceBus Saga是企业集成模式Process Manager中描述的book的变体。

要了解何时使用Saga,必须要有它。假设您只使用常规消息处理程序来实现新的用户注册过程。在某个时间点,您发现只有40%的全新注册人确认其电子邮件地址并成为活跃的用户帐户。您有两件事需要解决。

  1. 提醒新注册人在注册后24小时内发送提醒确认其电子邮件。
  2. 在48小时内从数据存储中删除注册人信息(例如电子邮件)以符合GDPR
  3. 现在如何使用常规消息处理程序执行此操作?处理程序将通过生成带有确认链接的电子邮件来接收初始请求(第一条消息,m1)以启动注册。一旦处理程序完成,它就完成了。但您的流程尚未完成。这是一个长期运行的逻辑过程,必须在完成之前的48小时内完成。它不再仅仅是单个消息处理,而是此时的工作流程。具有多个检查点的工作流程。类似于状态机。要从一种状态转移到另一种状态,必须满足某种条件。在NServiceBus的情况下,那些将是消息。任何用户操作都不会触发24小时后发送提醒的消息(让我们称之为m2)。这是一个“系统”消息。应该自动启动的定时消息。如果验证链接未激活,则指示系统删除注册人信息的消息也是如此。可以观察到主题:需要在将来安排消息以重新保持工作流程,并从上次离开的状态继续。

    这就是超时。这些是从上次在某个时间点 - 几分钟,几小时,几天,几个月,一年中留下的时间点重新保湿/继续传奇/工作流程的请求。

    这就是这种工作流程看起来像一个传奇(过于简化并且不考虑所有边缘情况)。

    class RegistrationWorkflow : 
      Saga<WorkflowState>,
      IAmStartedByMessages<RegisterUser>,
      IHandleMessages<ActivationReceived>,
      IHandleTimeouts<NoResponseFor24Hours>,
      IHandleTimeouts<NoResponseFor48Hours>
    {
      protected override void ConfigureHowToFindSaga(SagaPropertyMapper<WorkflowState> mapper)
      {
        // omitted for simplicity, see message correlation
        // https://docs.particular.net/nservicebus/sagas/message-correlation
      }
    
      public async Task Handle(RegisterUser message, IMessageHandlerContext context)
      {
        Data.RegistrationId = message.RegistrationEmail;
    
        await RequestTimeout<NoResponseFor24Hours>(context, TimeSpan.FromHours(24));
      }
    
      public async Task Handle(ActivationReceived message, IMessageHandlerContext context)
      {
        Data.ConfirmationReceived = true;
    
        // email was confirmed and account was activated
        await context.Send(new PromoteCandidateToUser 
        { 
          CandidateEmail = Data.RegistrationEmail 
        });
    
        MarkAsComplete()
      }
    
      public async Task Timeout(NoResponseFor24Hours timeout, IMessageHandlerContext context)
      {
        if (Data.ConfirmationReceived)
        {
          return;
        }
    
        await context.Send(new SendReminderEmailToActivateAccount { Email = Data.RegistrationEmail });        
    
        await RequestTimeout(context, TimeSpan.FromHours(24), new NoResponseFor48Hours());
      }
    
      public async Task Timeout(NoResponseFor48Hours timeout, IMessageHandlerContext context)
      {
        if (Data.ConfirmationReceived)
        {
          return;
        }
    
        context.Send(new CleanupRegistrationInformationForGDPRCompliancy 
        { 
          RegistrationEmail = Data.RegistrationEmail 
        });
    
        MarkAsComplete();
      }
    }
    

    由于这是状态机,因此状态在Saga调用之间保持不变。调用可能是由传奇可以处理的消息(RegisterUserActivationReceived)引起的,也可能是由到期的超时(NoResponseFor24HoursNoResponseFor48Hours)引起的。对于这个特定的传奇,状态由以下POCO定义:

    class WorkflowState : ContainSagaData
    {
      public string RegistrationEmail { get; set; }
      public bool ConfirmationReceived { get; set; }
    }
    

    超时只不过是普通的IMessage被推迟了。此样本中使用的超时时间为

    class NoResponseFor24Hours : IMessage {}
    class NoResponseFor48Hours : IMessage {}
    

    希望这澄清了Sagas的概念,Timeouts是什么以及如何使用它们。我没有进入Message CorrelationSaga Concurrency以及其他一些细节,因为这些细节可以在您提到的文档网站上找到。这将我们带到下一点。

      

    我已多次阅读其网站上的文档。这绝对是可怕的。我一遍又一遍地阅读相同的文章,我无法理解他们想要实现的目标。

    该网站有一个您绝对应该提供的反馈机制。 enter image description here

      

    此外,互联网上几乎没有与此主题相关的资源。

    希望看到您在此主题上发布博客(或一系列帖子)。通过这样做,你将有积极的贡献。

    完全免责声明:我在NServiceBus上工作