Java 设计非实时、非阻塞、结果相关的系统
上下文:Java 设计非实时、非阻塞、结果相关的系统,java,multithreading,asynchronous,architecture,system-design,Java,Multithreading,Asynchronous,Architecture,System Design,上下文: 1) 我们有一个调度器,它通过以阻塞方式调用另一个rest调用来拾取作业并处理它们 2) 调度程序线程需要等待rest调用完成,然后根据结果执行另一项任务 3) 这是实时的,没有任何限制 问题陈述: 1) 我们想要的是在外部调用完成后立即释放调度程序线程,因为外部调用需要很长时间才能完成 2) 我们应该被告知从外部呼叫收到的结果,因为我们需要根据结果进行一些处理 我心中的想法: 1) 我们没有使用同步Http调用调用外部系统,而是 可以将事件推送到队列中 2) 另一个系统的Api使用者
1) 我们有一个调度器,它通过以阻塞方式调用另一个rest调用来拾取作业并处理它们 2) 调度程序线程需要等待rest调用完成,然后根据结果执行另一项任务 3) 这是实时的,没有任何限制 问题陈述: 1) 我们想要的是在外部调用完成后立即释放调度程序线程,因为外部调用需要很长时间才能完成 2) 我们应该被告知从外部呼叫收到的结果,因为我们需要根据结果进行一些处理 我心中的想法: 1) 我们没有使用同步Http调用调用外部系统,而是 可以将事件推送到队列中 2) 另一个系统的Api使用者将从队列中读取事件并执行长时间运行的任务。和后处理将结果推回到不同主题的队列 3) 我们的系统现在可以从队列中读取响应(第二个主题)并执行必要的操作 这是我的设计方法之一 我需要关于我们是否能以某种方式改进设计的建议 1) 这可以在不引入队列的情况下完成吗
2) 有没有更好的方法来实现异步处理?如果您想避免使用队列,我可以考虑其他两种方法,例如: 1) 我们可以将事件推送到队列,而不是使用同步Http调用调用外部系统 备选方案a) 您执行一个同步HTTP GET来告诉另一个系统您希望执行某个作业(另一个系统快速回复“200OK”以确认它收到了请求) 备选方案b) 您执行一个同步HTTP GET来告诉另一个系统您希望执行某个作业(另一个系统快速响应“200OK”和一个唯一的ID来标识要执行的作业) 2) 另一个系统的Api使用者将从队列中读取事件并执行长时间运行的任务。和后处理将结果推回到不同主题的队列。 3) 我们的系统现在可以从队列中读取响应(第二个主题)并执行必要的操作 备选方案a) 在接收到请求后,另一个系统执行长时间运行的计算,然后当它准备就绪时,它向原始系统发出同步HTTP调用,通知作业已准备就绪 备选方案b) 收到请求后,另一个系统执行长时间运行的计算。
原始系统不知道作业是否完成,因此它会在特定时间进行轮询(对不同的REST API执行同步HTTP访问),以提供作业ID,以确定作业是否准备就绪。我不理解“我们想要的是在进行外部调用时释放调度程序线程”。这是分配线程的时间点,而不是释放线程的时间点。我们有一个调度程序,它通过阻塞方式调用另一个rest调用来拾取作业并处理它们。由于调用花费了太多的时间,我们需要使其无阻塞,但我们必须根据调用的结果进行一些处理。我们可以在非实时的基础上做这件事,但这并不能以任何方式回答我的问题。我编辑了这个问题。现在好了吗?我可不想避免使用队列。我想用最好的设计来完成手头的工作,只有在需要的时候才使用额外的资源(同时考虑到成本)。我理解。添加消息传递队列会增加成本,还增加了确保队列始终运行的问题。这也增加了系统的复杂性。但另一方面,如果您想要恢复能力,消息传递队列是最好的选择。它将客户机/服务器解耦,并且在高可用性配置中部署消息队列时,它将保证不会丢失任何消息。总之:为了协调两个系统之间的工作,不可能一般假设使用消息队列的系统比没有消息队列的系统更好或更差。(这取决于您的需求、预算和实施解决方案的可用时间)让我们在此处删除成本。。。我需要建立一个可扩展的容错系统。那么您将如何进行呢?在高可用性配置中部署的消息队列(RabbitMQ或Kafka)。