如何计算Java响应式进程所花费的总时间

问题描述 投票:0回答:1

我有一个 Java 反应式 spring boot 应用程序,我正在执行以下逻辑,我想记录完成整个方法需要多少时间。我可以更改方法签名,但想保持原样。

public Flux<void> verifyStuff(){
  return client.getSomeData1(query)
        .doOnNext(
            result1 -> log.info("Retrieved '{}' ", result1.size()))
        .flatMapMany(result1 -> Flux.fromStream(result1.stream())
            .concatMap(this::verifyresult1()));
 }

因此,该方法实际上反应性地获取结果列表并按顺序调用另一个服务。

我尝试使用 elapsed() 但无法理解它是如何工作的。 还尝试了以下版本。

public Flux<void> verifyStuff(){
  StopWatch stopWatch = new StopWatch();
    stopWatch.start();
  return client.getSomeData1(query)
        .doOnNext(
            result1 -> log.info("Retrieved '{}' ", result1.size()))
        .flatMapMany(result1 -> Flux.fromStream(result1.stream())
            .concatMap(this::verifyresult1())
        .doFinally(signalType -> {
          stopWatch.stop();
          log.info("To execution time for verifying marketplace partners is {}ms",
              stopWatch.getTotalTimeMillis());
        });;
 }

但这会在“verifyresult1”下解决所有通量之前完成日志

java spring-boot spring-webflux project-reactor reactive
1个回答
0
投票

您对秒表方法的看法是正确的,但您遇到了计时问题,因为当前设置中的“

doFinally
”是在“
verifyStuff
”方法完成之后、但在所有异步操作之前执行的助焊剂已完成。这是因为 Flux 操作(例如
flatMapMany
)是异步且非阻塞的。因此,当 Flux 仍在处理项目时,可以触发
doFinally

要正确测量整个方法的执行时间,您需要确保

StopWatch
在异步流程开始时启动,并在整个 Flux 管道完成时停止。

尝试使用

elapsed()
运算符 利用 Flux 中的
elapsed()
运算符来测量完成整个 Flux 序列所需的时间。
elapsed()
运算符提供
Tuple2<Long, T>
,其中第一个值是经过的时间(以毫秒为单位),第二个值是实际发出的项目。

如果有效,请尝试:

import reactor.core.publisher.Flux;

public Flux<Void> verifyStuff() {
    // Record the start time using elapsed
    return client.getSomeData1(query)
        .doOnNext(result1 -> log.info("Retrieved '{}' ", result1.size()))
        .flatMapMany(result1 -> Flux.fromStream(result1.stream())
            .concatMap(this::verifyresult1))
        .elapsed()  // This will emit a tuple of elapsed time and the last emitted item
        .doOnTerminate(() -> log.info("Total execution time: {}ms", elapsed().getT1()));
}
© www.soinside.com 2019 - 2024. All rights reserved.