【问题标题】:Designing non-real time, non-blocking, result-dependent system设计非实时、非阻塞、结果相关的系统
【发布时间】:2017-06-27 09:56:54
【问题描述】:

上下文:

1) 我们有一个调度程序,它通过以阻塞方式调用另一个 rest-call 来获取作业并处理它们。

2) 调度程序线程需要等待休息调用完成,然后根据结果执行一些其他任务。

3) 对于实时性没有任何限制。

问题陈述:

1) 我们想要的是在进行外部调用后立即释放调度程序线程,因为外部调用需要大量时间才能完成。

2) 我们应该被告知从外部调用收到的结果,因为我们需要根据结果进行一些处理。

我的想法:

1) 我们不是使用同步 Http 调用来调用外部系统,而是 可以将事件推送到队列中。

2) 另一个系统的 API 消费者将从队列中读取事件并执行长时间运行的任务。并且后期处理将结果推送回不同主题的队列。

3) 我们的系统现在可以从队列(第二个主题)中读取响应并执行必要的操作。

这是我的设计方法之一

我需要关于我们是否可以以某种方式改进设计的建议。

1) 在不引入队列的情况下可以做到这一点吗?

2) 有没有更好的方法来实现异步处理?

【问题讨论】:

  • 我不明白“我们想要的是在进行外部调用时释放调度程序线程”。这是您将分配一个线程而不是释放它的点。
  • 我们有一个调度程序,它通过以阻塞方式调用另一个 rest-call 来获取作业并处理它们。由于调用时间太长,我们需要让它成为非阻塞的,但是我们必须根据调用的结果做一些处理。我们可以在非实时基础上做到这一点
  • 这并不能以任何方式回答我的问题。
  • 我编辑了这个问题。现在还好吗?

标签: java multithreading asynchronous architecture system-design


【解决方案1】:

如果您想避免使用队列,我可以考虑其他 2 个替代方案,例如:

1)我们可以将事件推送到队列中,而不是使用同步Http调用来调用外部系统。

另一种选择)

您执行同步 HTTP GET 来告诉其他系统您希望执行某个作业(其他系统快速回复“200 OK”以确认它收到了请求)。

备选方案 b)

您执行同步 HTTP GET 来告诉其他系统您希望执行某个作业(其他系统快速回复“200 OK”和一个唯一 ID 来标识要执行的作业)

2) 另一个系统的 API 消费者将从队列中读取事件并执行长时间运行的任务。并且后期处理将结果推送回不同主题的队列。 3) 我们的系统现在可以从队列(第二个主题)中读取响应并执行必要的操作。

另一种选择)

收到请求后,另一个系统会执行长时间运行的计算,然后当它准备好时,它会向您的原始系统发出同步 HTTP 调用,以通知作业已准备好。

备选方案 b)

收到请求后,另一个系统执行长时间运行的计算。 原始系统不知道作业是否已完成,因此它会在特定时间轮询(对不同的 REST API 执行同步 HTTP GET)提供作业 ID,以确定作业是否准备就绪。

【讨论】:

  • 我不想避免使用队列。我想用最好的设计完成手头的工作,仅在需要时才使用额外的资源(考虑到成本)。
  • 我明白了。添加消息队列会增加成本并增加确保队列始终运行的问题。它还增加了系统的复杂性。但另一方面,如果您想要弹性,消息队列是最佳选择。它将客户端/服务器解耦,当消息队列部署在高可用性配置中时,它提供了不会丢失任何消息的保证。
  • 总结:为了协调两个系统之间的工作,不可能做出一个一般假设,即使用消息队列的系统比没有它的系统更好或更差。 (这取决于您的要求、预算和实施解决方案的可用时间)
  • 让我们去掉这里的成本......我需要构建一个可扩展和容错的系统。那你会怎么做呢?
  • 在高可用性配置中部署的消息队列(RabbitMQ 或 Kafka)。
猜你喜欢
  • 1970-01-01
  • 2017-02-10
  • 2019-10-30
  • 2023-03-28
  • 2014-05-27
  • 2018-06-11
  • 2014-02-17
  • 1970-01-01
  • 2020-10-09
相关资源
最近更新 更多