代码之家  ›  专栏  ›  技术社区  ›  Seb

查询微服务体系结构中的异步操作状态

  •  0
  • Seb  · 技术社区  · 5 年前

    我们正在重新设计几个REST API端点,以转换为微服务体系结构。

    在这里我们正在研究终点 /invitations/:id/confirm .

    此终结点创建 User , Account 使用提供的 Invitation .

    我们有三个集合 邀请 , 用户 帐户 .

    我们的名义流量 目前 以下是:

    • 检查是否 邀请 存在
    • 确保邀请可以确认
    • 创建 用户
    • 创建 帐户
    • 删除 邀请
    • 返回 UserId

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

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

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

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

    这个 请求邀请确认 事件将触发一个负责协调跨服务通信的传奇

    • 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 终点。

    这就是我们困惑的地方。当状态可能完全不同于一个传奇到另一个传奇时,如何提供一个端点?

    谢谢

    0 回复  |  直到 5 年前
        1
  •  0
  •   Alexey Zimarev    5 年前

    为了让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存储库(您有权访问),那么通过查看 CurrentState 属性,该属性位于用于保存saga的数据库中的saga状态中。