【问题标题】:Handling large simultaneous workloads using pub/sub?使用 pub/sub 处理大型同时工作负载?
【发布时间】:2021-09-27 03:46:20
【问题描述】:

我正在处理一个很大的问题。的操作必须基于事件同时启动。例如,用户输入目的地和日期,并希望获得 200 多个“旅行合作伙伴”的最佳优惠。

为了满足这一点,我正在计划一个事件驱动的架构,当用户提供适当的输入时,一条消息被发布到一个主题,并且这个主题有工作人员订阅它,这反过来会生成额外的事件,一个用于每个旅行合作伙伴都可以从中获得优惠。

所以本质上:

  • (1) 在提供用户输入时向主题"TRAVEL_DESTINATION_REQUEST" 发布消息
  • (2) 工作人员订阅了此主题
  • (3) 工作人员在 (2),对于系统中的每个旅行伙伴,将带有数据 {date:..., destination:...,travel_partner_id: ...etc} 的事件发布到主题 FIND_OFFER
  • (4) 工作人员订阅了FIND_OFFER 查询travel_partner_id 并将响应保存在某处。

因此,如果您有 200 个旅行合作伙伴,则上面会将 200 个事件推送到 FIND_OFFER 主题,供工作人员处理每个用户查询。

你会这样解决问题吗?如果不是,你会怎么做?按顺序显然是不可能的,因为我们不能让用户坐在那里等待,而且旅行合作伙伴 api 调用的响应时间可能会有所不同......

在 GKE 世界中,发布/订阅是否适合这种方法?有谁知道 pod 负载平衡是否会导致此模型出现任何问题?

【问题讨论】:

标签: design-patterns architecture google-cloud-pubsub event-driven-design


【解决方案1】:

免责声明:我刚刚加入 StackOverflow,并且是 EDA 和事件支持领域的先驱 Solace 的成员。

这是一个经典的 pubsub 问题,可以使用任何 JMS 代理或 Solace 或 Kafka 代理来提供更好的 QoS。

做一些假设 - 请求是从 UI 触发的,期望在合作伙伴到达时近乎实时地呈现响应。 UI 刷新可以由您选择的良好前端框架/堆栈单独进行 - 问题的关键在于后端如何处理。

事件驱动的设计非常适合此要求 - 流程如下所示:

  • 向主题 TRAVEL_DESTINATION_REQUEST 发布请求消息,并将“reply-to”设置为队列 TRAVEL_DESTINATION_RESPONSE
  • 订阅者(合作伙伴)订阅主题 TRAVEL_DESTINATION_REQUEST 并将其响应发送到“回复”目的地
  • 发布者,并行运行一个线程(或回调),检查 TRAVEL_DESTINATION_RESPONSE 队列上的响应消息是否到达,并采取适当的措施(将其推送到客户端、保存在数据库中或类似的东西)确保所有响应都是已处理

几乎任何代理都可以处理这种用例 - 但是,当您想要同时处理多个此类请求而不混合响应、不增加主题、队列和消耗服务时,就会出现复杂性,从而导致资源溢出和管理开销。

这是一个使用 Solace 作为 EDA 代理的可能解决方案。 Solace 的 TOPIC 方案是独一无二的,非常适合这一要求。主题不仅仅是一个名称,而是一种可以将动态细节编码为主题名称中的级别的方案,这在处理消息时很有用。 Solace 主题是分层的,允许使用通配符根据主题中的不同级别进行过滤。

借助 Solace 及其分层主题 - 我们可以按如下方式进行管理:

  1. 发布关于主题 TRAVEL_DESTINATION_REQUEST/ 的请求并将回复目的地设置为 RESPONSE_QUEUE
  2. 所有合作伙伴都使用通配符 TRAVEL_DESTINATION_REQUEST/* 订阅主题,以便他们接收所有旅行请求消息
  3. 发布者本身或单独的服务都可以连接到 RESPONSE_QUEUE 并检索响应

最后一步 (3) 是主题层次结构的最大优势发挥作用的地方。您可以创建到队列 RESPONSE_QUEUE 的多个同时客户端连接,并为每个连接提供不同的订阅 - 这就像为每个发布的请求 ID 生成消费者服务,然后连接到队列并订阅响应主题TRAVEL_DESTINATION_RESPONSE/.

经过一段时间或一个逻辑条件后,这些消费者服务可以退出,标志着请求处理完成。至于这个服务内部发生了什么,它是业务逻辑 - 持久化到数据库或将其推送到前端或其他东西。

希望这会为您提供一种使用 Solace 作为代理的方法来满足您的要求。我确信,其他选项可用且有效,我只是分享一种基于 Solace Broker 的有效方法。

【讨论】:

    【解决方案2】:

    我对此做出回应是因为过去 2 天没有人这样做 - 而不是因为我是这方面的专家。所以考虑到这一点......

    一定要牢记用户体验。您想向用户提供 200 个结果吗?不确定我是否会查看 200 个结果,即使用户体验非常流畅。

    基本上,您需要某种编排来协调步骤 2、3 和 4 - 不仅仅是发出请求,还要处理返回的数据。这种编排的一个关键方面是决定在“未雨绸缪”的场景中做什么,特别是那些涉及错误或延迟的场景:

    • 如果伙伴 168 在 X 秒内没有回复,你会怎么做?
    • 如果 199 个合作伙伴已回复但 168 个未回复(仍在时间之内),您会等吗?
    • 如果您即将超时,而您只有 30 条回复,您会怎么做?
    • 如果您之前对合作伙伴 168 的请求超时,您现在是否在当前请求中再次尝试? ...或者你会在 10 秒内尝试一下吗? ... UI 是否关心您目前只有 199 个合作伙伴在工作?

    如果您可以在脑海中(以及在图表中)将其映射出来,那么该思考过程应该会对您有所帮助。

    以事件为中心的解决方案和工具应该善于帮助协调结果 - 例如。帮助您决定何时将内容返回到 UI 链。看一下一般的事件/异步设计模式,如果您已经考虑了特定技术,请查看它们有哪些模式/参考思想。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 2021-10-09
      • 2015-05-21
      • 2022-01-02
      • 2011-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多