问题描述
我正在解决一个很大的问题。的操作必须同时基于事件启动。例如,用户输入目的地和日期,并希望从 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 世界中,pub/sub 是这种方法的理想选择吗?有谁知道 pod 负载平衡是否会导致此模型出现任何问题?
解决方法
我对此做出回应是因为在过去 2 天内没有人做出回应 - 而不是因为我是这方面的专家。所以考虑到这一点...
一定要牢记用户体验。您想向用户提供 200 个结果吗?不确定我会不会查看 200 个结果,即使 UX 非常流畅。
基本上,您需要某种编排来协调步骤 2、3 和 4 - 不仅是发出请求,还要处理返回的数据。这种编排的一个关键方面是决定在“未雨绸缪”的情况下做什么,特别是那些涉及错误或延迟的情况:
- 如果合作伙伴 168 在 X 秒内没有回复,你会怎么做?
- 如果 199 位合作伙伴已做出回应,但 168 位合作伙伴尚未回应(仍在规定时间内),您会等待吗?
- 如果您即将超时,而您只有 30 条回复,您会怎么做?
- 如果您之前对合作伙伴 168 的请求超时,您现在是否在当前请求中再次尝试? ...或者你会在 10 秒内尝试它们吗? ...用户界面是否关心您现在只有 199 个合作伙伴在工作?
如果您能在头脑中(并在图表中)将其映射出来,那么该思考过程应该会对您有所帮助。
以事件为中心的解决方案和工具应该擅长帮助协调结果 - 例如帮助您决定何时将内容返回到 UI 链。大致了解事件/异步设计模式,如果您已经有了特定的技术,请查看它们有哪些模式/参考想法。
,免责声明:我刚刚加入 StackOverflow,是 EDA 和事件支持领域的先驱 Solace 的成员。
这是一个经典的发布订阅问题,使用任何 JMS Brokers 或 Solace 或 Kafka Broker 都能很好地解决这个问题,以获得更好的 QoS。
做一些假设 - 请求是从 UI 触发的,期望在来自合作伙伴的响应到达时近乎实时地呈现响应。 UI 刷新可以由您选择的良好前端框架/堆栈单独处理 - 问题的关键在于后端如何处理。
事件驱动的设计非常适合此要求 - 流程如下所示:
- 将请求消息发布到主题 TRAVEL_DESTINATION_REQUEST,并将“回复”设置为队列 TRAVEL_DESTINATION_RESPONSE
- 订阅者(合作伙伴)订阅主题 TRAVEL_DESTINATION_REQUEST 并将他们的响应发送到“回复”目的地
- 发布者,并行运行一个线程(或回调),检查响应消息到达 TRAVEL_DESTINATION_RESPONSE 队列并采取适当的措施(将其推送到客户端,保存在数据库中,或类似的)确保所有响应已处理
几乎所有 Broker 都可以处理这种用例 - 但是,当您想要同时处理多个此类请求而不混合响应、主题、队列和使用服务不扩散,从而导致资源溢出和管理开销时,复杂性就会出现。
>这是一个使用 Solace 作为 EDA Broker 的可能解决方案。 Solace 的 TOPIC 方案是独一无二的,非常适合此要求。主题不仅仅是一个名称,而是一种可以将动态细节编码为主题名称中的级别的方案,这在处理消息时很有用。 Solace 主题是分层的,允许使用通配符根据主题中的不同级别进行过滤。
使用 Solace 及其分层主题 - 我们可以按如下方式进行管理:
- 发布关于主题 TRAVEL_DESTINATION_REQUEST/ 的请求并将回复目的地设置为 RESPONSE_QUEUE
- 所有合作伙伴都使用通配符 TRAVEL_DESTINATION_REQUEST/* 订阅主题,以便他们收到所有旅行请求消息
- 发布者本身或单独的服务都可以连接到 RESPONSE_QUEUE 并检索响应
最后一步 (3) 是主题层次结构的最大好处发挥作用的地方。您可以创建到队列 RESPONSE_QUEUE 的多个并发客户端连接,并为每个连接提供不同的订阅 - 这就像为每个发布的请求 ID 生成一个消费者服务,后者又连接到队列并订阅响应主题TRAVEL_DESTINATION_RESPONSE/。
经过一段时间或逻辑条件,这些消费者服务可以退出标记请求处理完成。至于这个服务内部发生了什么,它是业务逻辑 - 持久化到数据库中或将其推送到前端或其他东西。
希望这能提供一种使用 Solace 作为 Broker 来满足您的要求的方法。我敢肯定,还有其他可用且有效的选项,我只是分享一种基于 Solace Broker 的有效方法。