【问题标题】:Query asynchronous operation state within a micro service architecture查询微服务架构内的异步操作状态
【发布时间】:2019-09-20 19:26:00
【问题描述】:

我们正在重新设计少数 REST API 端点以过渡到微服务架构。

我们正在处理端点/invitations/:id/confirm

此端点使用提供的Invitation 创建UserAccount

我们有 3 个聚合 InvitationUserAccount

我们目前的标称流量是:

  • 检查Invitation是否存在
  • 确保可以确认邀请
  • 创建User
  • 创建Account
  • 删除Invitation
  • 返回UserId

这个操作是在进程中完成的,这解释了为什么我们可以立即返回一个 UserId。我们只需从数据库加载我们的聚合,执行相关的业务逻辑并持久化结果。

引入微服务将需要异步处理。换句话说,我们应该向总线发送命令并返回状态码 202。

在我们的计划中,我们要触发一个名为RequestInvitationConfirmation 的命令。实例化此命令时将进行基本验证。

然后这个命令将通过总线发送给消费者负责: - 加载邀请聚合(确保它存在) - 调用 RequestConfirmation 方法(将检查是否可以确认邀请) - 引发InvitationConfirmationRequested 事件

InvitationConfirmationRequested 事件将触发一个 SAGA,负责协调跨服务通信

  • OnInvitationConfirmationRequested
    • 发送CreateUser 命令
  • OnUserCreated
    • 发送CreateAccount 命令
  • OnAccountCreated
    • 发送DeleteInvitation命令
  • OnInvitationDeleted
    • 提高InvitationConfirmed

由于它是异步的,我们需要提供一种获取当前操作状态的方法。我看到 (https://www.adayinthelifeof.nl/2011/06/02/asynchronous-operations-in-rest/, https://asyncrestapi.docs.apiary.io/#) 一种常见的方法 是提供/queue/:id/actions/:id 端点。

这就是我们感到困惑的地方。当状态可能与 SAGA 完全不同时,如何提供单个端点?

谢谢

【问题讨论】:

    标签: domain-driven-design cqrs state-machine masstransit bus


    【解决方案1】:

    为了让您的 saga 在单个流范围内处理消息,您必须将所有消息与适当的实例相关联。当一个saga被第一条消息启动时,saga身份是按照规则生成的:

    Event(() => ItemAdded, x => x.CorrelateBy(cart => cart.UserName, context => context.Message.UserName)
        .SelectId(context => Guid.NewGuid()));
    

    所以这个 id 将被用作你的 saga 的标识,它被持久化到 saga 存储库中。

    class ShoppingCart :
        SagaStateMachineInstance
    {
        public Guid CorrelationId { get; set; }
        public string CurrentState { get; set; }
    

    这里CorrelationId是saga id,因此是整个过程的相关id。

    如果您有权访问您的 saga 存储库(并且您确实如此),那么通过在用于持久化 saga 的数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-24
      • 2017-10-10
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 2020-03-04
      • 2015-12-26
      相关资源
      最近更新 更多