将异步 API 调用与 Java 同步



请考虑以下场景:

服务
  1. A 调用服务 B 以完成任务。
  2. 服务 B 返回"OK",并继续以异步方式执行任务。
  3. 由于 A 从 B 收到 OK,因此它还会向调用它的人返回响应。

我希望能够同步此任务。服务 B 是可自定义的,因此它可以在它应该执行的任务结束时进行 API 调用。我的想法是:

服务
  1. A 调用服务 B 以完成任务。
  2. 服务 B 返回"OK",并继续以异步方式执行任务。
  3. 服务 A 接收来自 B 的响应,但不返回。
  4. 服务 B 结束任务,并向 A 发送 API 调用(到某个端点等(。
  5. 服务 A 接收然后返回。

这只是一个例子。事实上,服务A是一个Spring启动应用程序,而服务B是我们构建的第三方软件。

是否可以像使用 Java/Spring 同步异步 API 调用?我尝试在网上搜索这个,但找不到合适的东西。

因此,根据您的请求数据的外观,我将假设有一个从服务 A 发送到服务 B 的唯一 ID。

如果是这种情况,您可以使用此 id 作为相关 ID,并可以使用 CompletableFutures 实现等待策略。当服务 B 响应"OK"时,服务 A 可以使用唯一 ID 作为键创建一个可完成的未来,并对此调用 get((,这将阻止直到调用 complete((。当服务 B 完成其处理后,它可以调用服务 A 上的 API 以及相关 ID,现在可用于完成将来的工作。

下面是一些基本代码,只是为了说明这个想法

public class ServiceA {
private Map<String, CompletableFuture<String>> correlationStore;
public ServiceA() {
correlationStore = new HashMap<>();
}
public String performTask(String id, String data) {
CompletableFuture<String> futureResult = new CompletableFuture<>();
String submissionResult = callServiceB(id, data);
if (!"OK".equalsIgnoreCase(submissionResult)) {
return "FAILED";
}
//Service B has accepted the request and is busy processing the result
correlationStore.put(id, futureResult);
String response = null;
try {
//Set a timeout to whatever is sensible
response = futureResult.get(30, TimeUnit.SECONDS); // Thread is now blocked until complete() is called
} catch (InterruptedException | ExecutionException | TimeoutException e) {
if (e instanceof TimeoutException) {
correlationStore.remove(id);
}
//Handle failure depending on your requirements
}
return response;
}
//This is called from API call back from Service B
public void onResponse(String id, String responseData) {
CompletableFuture<String> pendingResult = correlationStore.remove(id);
if (pendingResult != null) {
pendingResult.complete(responseData);
} else {
//Handle the scenario where there is not future waiting for a response
}
}
}

但是,使用这种类型的方法,需要考虑许多事项,例如,如果服务 B 从未实际回调服务A 并返回结果,或者更确切地说,如果等待服务 B 响应超时,删除未来,然后在稍后阶段返回响应, 你应该怎么做来处理这个问题?

但现在这完全取决于您的服务 A 的作用,以及围绕失败的特定情况,即将请求的状态存储在服务 A 中,并提供查询状态的机制等。

但是,我强烈建议您根据项目的灵活性,研究中间件队列机制,例如RabbitMQ/Kafka/Pulsar等,因为它们都为基于工作队列的架构提供了强大的功能,并且可以根据您的情况为您提供有用的功能。

最新更新