You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webflux/Reactor链式依赖API调用出现重复请求如何优化避免?

问题原因及解决方案

根本原因

你推测的触发逻辑完全正确。Reactor 中默认所有Mono/Flux均为冷发布者,每接收一次订阅请求,就会从头执行一次上游的完整处理链路。你的代码中users这个Mono对象被触发了两次订阅:

  • 第一次是构造parents对象时,依赖users的结果触发订阅
  • 第二次是执行Flux.merge(users, parents)时,对users的第二次订阅
    两次订阅对应两次第二次API调用,因此总共产生4次API请求。

解决方案

方案1:添加缓存操作符复用结果

在users的定义末尾添加cache()操作符,第一次订阅得到的结果会被缓存,后续所有订阅直接复用缓存结果,不会重新触发上游的API调用。同时可优化原有冗余的map+flatMap写法,合并为单个flatMap:

Mono<List<Book>> books = bookService.find(params); //1st API call
Mono<List<User>> users = books.flatMapMany(Flux::fromIterable)
    .map(User::getId)
    .collectList()
    .flatMap(userService::findUsers) //2nd API call,合并原有冗余写法
    .cache(); // 新增:缓存调用结果,避免重复执行API

Mono<List<User>> parents = users.flatMapMany(Flux::fromIterable)
    .filter(user -> user.getParentId() != null)
    .map(User::getParentId)
    .collectList()
    .flatMap(userService::findUsers); //3rd API call,同样优化冗余写法

Mono<List<User>> usersWithParents = Flux.merge(users, parents)
    .flatMapIterable(Function.identity())
    .collectList();

该方案适合后续业务逻辑还需要单独复用users、parents对象的场景。

方案2:调整链式结构避免重复订阅

直接将后续处理逻辑放在flatMap内部,全程只对第二次API调用的结果订阅一次,无需额外缓存:

Mono<List<User>> usersWithParents = bookService.find(params) //1st API call
    .flatMapMany(Flux::fromIterable)
    .map(User::getId)
    .collectList()
    .flatMap(userService::findUsers) //2nd API call,仅执行1次
    .flatMap(users -> {
        // 基于已拿到的users查询父账号,无需再次订阅上游
        return Flux.fromIterable(users)
            .filter(user -> user.getParentId() != null)
            .map(User::getParentId)
            .collectList()
            .flatMap(userService::findUsers) //3rd API call
            .map(parents -> {
                // 合并两个结果集合
                List<User> allUsers = new ArrayList<>(users);
                allUsers.addAll(parents);
                return allUsers;
            });
    });

该方案没有额外缓存开销,链路逻辑更内聚,适合仅需要最终合并结果的场景。

内容的提问来源于stack exchange,提问作者KPACHblu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 13:45:00