我有一个服务,位于服务器 1 上。我们将其称为 PDFService
。 PDFService
获取文档并将它们拼接到一个 PDF 中。
但是,PDFService
只知道文档 ID。它依赖服务器2来获取文档的实际内容。
在PDFService
进程开始时,它会批量收集文档ID。当它有一个批处理时,它会将批处理中每个 id 的异步请求发送到服务器 2 上的队列(返回 204)。然后它将继续收集更多批处理并重复。
收集并发送所有批处理后,PDFService
将开始拼接过程。
与此同时,服务器 2 可能没有处理过、部分或全部文档并返回到服务器 1。服务器 2 可能会按照与其接收顺序不同的顺序返回文档。(每个文档将采用一个编译和返回的时间不同。)
服务器 1 必须按照发送的顺序缝合它们。因此,它必须等待文档 1,缝合它,等待文档 2,缝合它,等等。
到目前为止,我有一个 DocumentManager
类,它将所有文档 ID 保存在具有 null
值的 Map
中。当完成的文档从服务器 2 返回时,Map
将使用实际值(保存文档内容的对象)进行更新。这显然是错误的,因为 PDFService
必须使用 while null
+ sleep
,这很糟糕。
我的问题是:如果需要,如何让 PDFService “等待”每个文档? 将 CompletableFuture
对象添加到我的 Map
看起来很有希望,但我不知道如何使用它,或者这是否是正确的方法。
(这是我的第一个问题,请提供建设性的反馈!)
最佳答案
嗯嗯嗯... 我可以推荐您查看一些企业集成框架,例如“Spring Integration”、“Apache Camel”、“MuleSoft”等。这样的框架可以处理所有等待、异步、并行、聚合等事情,这对你来说会更容易。
总体情况
it will send an async request for each id in the batch to a queue on Server 2
您已经提到了队列,因此使用 JMS 队列是可能的解决方案之一。
- Server1 将 Server2 的 documentId 发送到 JMS 队列
- Server2 监听队列并以实际文档响应 (服务器回复 JMS 消息的方式有多种可能性)
- Server1 监听响应,然后在收到所有响应后缝合所有响应
但使用 EIP 框架 JMS 不仅仅是一种可能性 - 例如,对于批处理,它可以是同步的,但可以并行调用 Server2...
顺便说一句:在没有任何框架(EIP 和/或 JMS)的情况下从头开始构建这样的东西是非常痛苦的,而且没有意义这样做。
关于java - 如何让服务等待带外进程完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52785185/