在Java Web应用程序中循环调用Web服务

时间:2018-03-12 15:43:24

标签: java performance web-services java-ee

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

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

当我们查询数据库时,我们发现有超过5000个此类客户将此ID标记为已标记。不幸的是,网络服务不接受ID列表,只能在一次网络呼叫中提供有关单个客户的信息。

现在,我们怀疑是否循环5000 ID并在此循环中多次调用Web服务是一个好主意。 作为测试运行,当我们调用500个ID的Web服务时,它在3.7分钟内完成,1000个Ids 7.25分钟。通过这个衡量标准,我们可以猜测,对于5000 Ids,大概需要40分钟。

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

有更好的方法吗?欢迎任何建议。 感谢。

2 个答案:

答案 0 :(得分:0)

  

不幸的是,网络服务不会接受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调整调用次数。

答案 1 :(得分:0)

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

我知道这有点改变了要求,但每2天发送一批产品和每小时发送一批产品之间差别不大。保留在列表中的每位客户将继续每两天收到一封电子邮件。

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