如何并行发送请求到异步服务并在 Java EE 应用程序中收集响应?

How to send requests parallel to asynchronous services and collect the responses in a Java EE application?

我开发了一个应用程序,它在某个时候开始从一堆服务中聚合信息。其中一些服务通过 SOAP 接口同步调用,其中一些服务异步工作 - 我必须向 JMS 队列 Q1 发送请求,并在某个时候得到对 Q2 的答复。

问题是应用程序在一个线程中发送请求并使用 MDB(消息驱动 Bean)处理响应。我想到的解决方案是将已经聚合的响应与一些 correlationId 存储在一些共享容器(如 ConcurrentHashMap)中。因此,当 MDB 获得响应时,它会查看共享容器并将响应添加到相应的记录中。

WildFly AS 上的应用 运行s 处于域 HA 模式。

  1. 我可以通过这种方法 运行 解决一些问题吗?就像容器将为集群中的每个节点实例化一个。
  2. 或者我可能不小心处理了太多的请求,以至于我存储了太多的响应,以至于我会得到 OutOfMemoryError?
  3. 解决此类问题的最佳方法是什么?

让我来回答你的问题:

  1. 对 JMS 服务调用的响应可能随时到达(很快:目标服务器关闭,操作员休息等)。所以你应该在数据聚合期间将请求存储在数据库中。
  2. 当您并行处理许多请求时,总是会出现性能问题。如果您有异步答案,您可以长时间存储 many-many 哈希值(或使用 SFSB activate/passivate),直到最后一个答案到达。第一个答案(部分)也解决了这个问题,因为它将大部分数据存储在数据库中,而只获取内存中的当前数据。而且更坚固。持久数据存在于服务器 crash/shutdown.
  3. 当您需要数据时,为所有人创建一个数据库条目,并在 header 中发送带有 PK 的请求。当一个答案到达时,它的 header 包含用于识别的相同 PK。 MDB 是接收它们的最佳方式。但仅使用它们来接收消息。通过 EJB 处理其内容。将消息内容同步委托给 EJB,并根据 EJB 的回答确认它们。在 EJB 处理的最后,获取属于当前聚合的未处理请求的 ID。如果没有,(从 db table 中删除查询条目并)调用适当的 EJB(通过 MDB?)以继续完成满足数据需求的工作。