首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Java中以同步方式处理异步回调?

如何在Java中以同步方式处理异步回调?
EN

Stack Overflow用户
提问于 2018-05-08 06:39:18
回答 2查看 8K关注 0票数 14

我有一个与建筑有关的问题。这是一个独立于语言的问题,但由于我来自Java背景,如果有人以Java的方式指导我,我会更容易。

基本上,我编写的中间件与基于SOAP的第三方服务进行通信。调用是异步的--在调用服务时,它通过响应01返回;这意味着第三方已经成功地接收到了请求。在原始SOAP请求中,每次必须提交一个回调URL,第三方实际上是在其中发送结果的。因此,调用特定服务实际上并不会立即返回结果;结果将在中间件中的一个单独的HTTP端点中接收。

现在,在我们的前端,我们不想让用户体验复杂化。我们希望我们的用户调用一个中间件函数(通过菜单项/按钮),并立即获得结果;将脏工作留给中间件。

请注意,从前端调用的中间件函数(比如X())和第三方推送结果的中间件端点URL(让我们称之为Y)是完全独立的。以某种方式,X()必须等待,然后取取在Y中捕获的结果,然后将结果返回到前端。

如何构建一个健壮的解决方案来实现上述行为?这幅画完美地描绘了我的案子。如有任何建议,将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-08 08:11:03

这个问题可能更多地是关于集成模式,而不是关于多线程。但是,可以使用异步调用和观察者模式的组合来编排同一个应用程序/JVM中的请求:

最好使用一个示例(利用您的Java知识)。检查以下试图复制您的场景的简单组件:

(第三方服务:)它公开了一个返回相关ID并启动长时间运行的执行的操作。

代码语言:javascript
运行
复制
class ExternalService {
    public String send() {
        return UUID.randomUUID().toString();
    }
}

您面向客户的服务:它接收一个请求,调用第三方服务,然后在向结果接收方注册后等待响应:

代码语言:javascript
运行
复制
class RequestProcessor {
    public Object submitRequest() {
        String correlationId = new ExternalService().send();

        return new ResultReceiver().register(correlationId).join();
    }
}

结果接收方:它向第三方服务公开一个操作,并维护一个内部相关注册表:

代码语言:javascript
运行
复制
class ResultReceiver {

    Map<String, CompletableFuture<Object>> subscribers;

    CompletableFuture<Object> register(String responseId) {
        CompletableFuture<Object> future = new CompletableFuture<Object>();
        this.subscribers.put(responseId, future);

        return future;
    }

    public void externalResponse(String responseId, Object result) {
        this.subscribers.get(responseId).complete(result);
    }
}

在这种情况下,期货、承诺、回拨都很方便。同步由初始请求处理器完成,以强制执行为客户端阻塞。

现在,这可能会引发一些问题,而这些问题在这个简单的类集中没有得到解决。其中一些问题可能是:

  • new ExternalService().send()new ResultReceiver().register(correlationId)之间的种族条件。这在ResultReceiver中是可以解决的,如果它不确定某些响应可以非常快(可以说是双向等待)。
  • 永远不会出现的结果:结果可能会花费太长时间,或者只是遇到错误。这些未来的API通常提供超时以强制取消请求。例如: 新ResultReceiver().register(correlationId) .get(10000,TimeUnit.SECONDS);
票数 12
EN

Stack Overflow用户

发布于 2018-05-08 06:53:40

那么这么做到底有什么问题呢?您只需创建一个API (中间件),它在第三方返回处理结果之前不会返回响应。前端将请求发送到X(),X()通过向Y()发送请求来处理该请求,然后继续轮询Y()以查看结果何时准备好,然后X()从Y()获取结果并将其发回前端。就像个门面。

在使用第三方服务方面存在一些您无法控制的问题,您应该考虑这些问题。首先,你需要实现某种断路器或超时。因为第三方服务可能挂起,永远不会处理结果(或者处理得太久,等待是没有意义的)。此外,您应该考虑一些有意义的方法来保持站点的运行,即使第三方服务不可用,或者已经更新了它们的API或其他什么东西,从而阻止了您使用它。

最后还有最后一个想法。为什么要制作已经实现异步同步的东西?它是这样做的,可能是因为它可能需要时间。阻塞前端很长一段时间等待结果,使用户体验不愉快,用户界面没有响应。通常更好的做法是坚持异步请求,并向用户展示他们正在处理的用户,但同时让他们做其他事情。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50227387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档