【问题标题】:Calling a web-service in a loop in Java web application在 Java Web 应用程序中循环调用 Web 服务
【发布时间】:2018-03-12 15:43:24
【问题描述】:

我们有一个基于 SOAP 的外部 Web 服务,该服务在提供 ID 时提供有关客户礼品卡余额的信息。此 ID 存储在我们的数据库中。

要求是找出所有标记了此 ID 的此类客户的余额,然后向他们发送电子邮件。该逻辑应该每隔一天作为计划作业运行一次。

当我们查询数据库时,我们发现有超过 5000 个这样的客户标记了这个 ID。不幸的是,网络服务不接受 ID 列表,并且只能在一次网络调用中提供有关单个客户的信息。

现在,我们怀疑循环 5000 个 Id 并在此循环中多次调用 Web 服务是否是个好主意。 作为测试运行,当我们为 500 个 Id 调用 Web 服务时,它在 3.7 分钟内完成,而 1000 个 Id 则为 7.25 分钟。通过这个度量,我们可以估计,对于 5000 个 Id,大约需要 40 分钟。

我们的 Web 应用程序是 JavaEE 6 堆栈,数据库是 Oracle。

有没有更好的方法来做到这一点?欢迎任何建议。 谢谢。

【问题讨论】:

  • 使用多个线程并行执行调用?
  • 对我来说,每隔一天 40 分钟听起来不错。你没有提到任何时序要求,所以我看不到任何优化原因。相反,我会考虑拆分工作,以便每隔几分钟完成一个请求,这样就不会在任何地方造成任何过载。

标签: java performance web-services jakarta-ee


【解决方案1】:

如果您可以编写一个确定性函数,该函数接受客户 ID 的输入,并为您提供一个从 0 到 47 的数字,表示在 2 天周期内发送这些电子邮件警报的小时数,您可以对发送的电子邮件进行分片并将其转换为每小时运行的作业。

我知道这会稍微改变要求,但是每 2 天发送一个批次和每小时发送一个较小的批次之间并没有太大区别。保留在您列表中的每位客户将继续每 2 天收到一封电子邮件。

另一种可能性是以多线程方式向 Web 服务发送查询。
Web 服务提供商应该真正考虑改变他们的界面。

【讨论】:

    【解决方案2】:

    很遗憾,网络服务不接受 ID 列表,并且可以 仅在一次网络呼叫中提供有关单个客户的信息。

    您确实应该与服务提供商联系以获得合适的解决方案。

    作为解决方法,如果 SOAP WS 允许进行多个并发调用,您可以通过多个线程对 WS 进行多次调用。
    为此,请创建一个RunnableCallable 实现,以执行对具有特定ID 的WS 的调用。

    例如,使用 Callable 和 ExecutorService 同时执行 10 次 WS 调用,您可以执行以下操作:

    MyWs myWs = ...; // web service stub
    List<Long> ids = ...; // ids to search
    
    List<Callable<Double>> callables = ids.stream()
                                          .map(id -> (Callable<Double>) () -> myWs.getBalance(id))
                                          .collect(Collectors.toList());
    
    ExecutorService executorService = Executors.newFixedThreadPool(10)
    List<Future<Double>> balanceFutures = executorService.invokeAll(callables);
    

    当然要根据运行JVM的机器的CPU来调整调用次数。

    【讨论】:

    • 感谢您的详细解释。我们仍在使用 Java 6,因此没有流 API。但除此之外,我对这个解决方案还有另一个疑问:ID 驻留在 DB 中,这意味着应用程序将查询 DB,然后从结果集中 1 个 1 读取 Id。一旦它读取了一个 Id,我们就使n/w 调用,那么我们如何“线程化”从结果集中读取并同时进行 n/w 调用。谢谢。
    猜你喜欢
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    相关资源
    最近更新 更多