我有一个 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”下解决所有通量之前完成日志
您对秒表方法的看法是正确的,但您遇到了计时问题,因为当前设置中的“
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()));
}