讲师中心 微信公众号
AI工具推荐 视频效率加速

Spring Boot 中并行调用多个 REST 接口的高效实现方案

老明同学_6484

老明同学_6484

发布时间:2026-01-18 18:17:02

|

338人浏览过

|

来源于php中文网

原创

Spring Boot 中并行调用多个 REST 接口的高效实现方案

本文介绍如何在 spring 应用中安全、高效地并行发起多个 rest 调用,解决因串行请求导致的接口响应延迟问题,并提供线程安全的响应聚合方案。

在构建基于 Spring 的微服务或网关类应用时,常遇到“父请求携带多个子请求”的典型场景:例如一个订单查询接口需同时调用库存、价格、用户画像、物流等下游服务。若对这 10–50 个子请求采用串行 HTTP 调用(如 RestTemplate 或 WebClient 同步阻塞调用),总耗时 ≈ 各子请求 RTT 之和,极易导致父接口 P95 延迟飙升、线程阻塞甚至雪崩。

根本解法是并行化 + 异步非阻塞。但直接使用 parallelStream().forEach() 会触发两个关键陷阱:

  1. 线程不安全写入:ArrayList 等非并发集合在多线程下 add() 可能引发 ConcurrentModificationException 或数据丢失;
  2. 变量有效性限制:Lambda 中引用的局部变量必须为 final 或“有效 final”,无法直接向外部 List/Map 添加结果。

✅ 正确做法是:选用线程安全容器 + 显式标识映射关系。根据子请求是否具备唯一 ID(数字索引或字符串键),选择以下任一方案:

React Best Practices 2 0.1.0
React Best Practices 2 0.1.0

React 与 Next.js 性能优化指南,源自 Vercel 工程团队。适用于编写、审查或重构 React/Next.js 代码时使用。

下载

✅ 方案一:子请求有连续整数 ID(如 0, 1, 2…N)

适用于子请求按顺序生成、ID 可作为数组下标的情形:

// 使用 synchronizedList 包装 ArrayList,保证 add(index, e) 线程安全
final List<ChildResponse> childResponses = 
    Collections.synchronizedList(new ArrayList<>(Collections.nCopies(childRequests.size(), null)));

childRequests.parallelStream()
    .forEach(request -> {
        ChildResponse response = callDownstreamApi(request); // 如 WebClient.post().retrieve().bodyToMono(...).block()
        childResponses.set(request.getId(), response); // 注意:setId() 必须返回 0~size-1 的有效索引
    });

// 后续按原始顺序组装父响应(顺序敏感场景必需)
ParentResponse parentResponse = buildParentResponse(childRequests, childResponses);

✅ 方案二:子请求有唯一字符串 ID(如 orderNo、skuId)

更通用、推荐的方式,天然支持无序响应与灵活关联:

// ConcurrentHashMap 线程安全,高性能,支持高并发 put
final Map<String, ChildResponse> responseMap = new ConcurrentHashMap<>();

childRequests.parallelStream()
    .forEach(request -> {
        ChildResponse response = callDownstreamApi(request);
        responseMap.put(request.getRefId(), response); // 如 request.getRefId() 返回 "SKU-1001"
    });

// 组装时仍按 childRequests 原始顺序遍历,确保响应顺序与请求一致
List<ChildResponse> orderedResponses = childRequests.stream()
    .map(req -> responseMap.get(req.getRefId()))
    .collect(Collectors.toList());
ParentResponse parentResponse = buildParentResponse(orderedResponses);

⚠️ 关键注意事项

  • 禁止使用 forEachOrdered 替代:它会强制串行执行,完全丧失并行意义;
  • 避免 parallelStream() 在 WebMvc 环境滥用:Servlet 容器线程池有限,并行流可能耗尽 Tomcat 线程,建议改用 WebClient + Project Reactor 的真正异步非阻塞(如 Flux.mergeSequential / Flux.zip);
  • 务必设置超时与熔断:并行调用放大失败风险,需为每个子请求配置独立 timeout 和 fallback;
  • 监控与追踪:为每个子请求添加 MDC 日志上下文(如 MDC.put("child_id", req.getId())),便于全链路排查。
✨ 进阶建议:在 Spring WebFlux 环境中,应优先采用响应式编程模型:Flux<ChildResponse> responses = Flux.fromIterable(childRequests) .flatMap(req -> webClient.post() .uri("/api/child") .bodyValue(req) .retrieve() .bodyToMono(ChildResponse.class) .timeout(Duration.ofSeconds(3)) .onErrorResume(e -> Mono.just(ChildResponse.empty(req.getId()))), 10 // 并发度控制,防压垮下游 ); Mono<ParentResponse> result = responses.collectList() .map(responsesList -> buildParentResponse(responsesList));

通过合理选择线程安全容器、明确请求-响应映射关系,并结合响应式编程演进,即可在保障数据一致性的同时,将数十个子请求的总体耗时从秒级降至单次最长子请求耗时(即“木桶最短板”),显著提升 API 性能与用户体验。

热门AI工具

更多
讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

相关专题

更多
如何配置Tomcat环境变量
如何配置Tomcat环境变量

配置Tomcat环境变量需要在系统中添加CATALINA_HOME变量,并将Tomcat的安装路径添加到PATH变量中。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

685

2023.10.26

idea如何集成Tomcat
idea如何集成Tomcat

idea集成Tomcat的步骤:1、添加Tomcat服务器配置;2、配置项目部署;3、运行Tomcat服务器;4、访问项目;5、注意事项;6、关闭Tomcat服务器。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

284

2024.02.23

怎么查看Tomcat源代码
怎么查看Tomcat源代码

查看Tomcat源代码的步骤:1、下载Tomcat源代码;2、在IDEA中导入Tomcat源代码;3、查看源代码;4、理解Tomcat的工作原理;5、参与社区和贡献;6、注意事项;7、持续学习和更新;8、使用工具和插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

469

2024.02.23

常见的tomcat漏洞有哪些
常见的tomcat漏洞有哪些

常见的tomcat漏洞有:1、跨站脚本攻击;2、跨站请求伪造;3、目录遍历漏洞;4、缓冲区溢出漏洞;5、配置漏洞;6、第三方组件漏洞。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

285

2024.02.23

tomcat日志乱码怎么解决
tomcat日志乱码怎么解决

tomcat日志乱码的解决办法:1、修改tomcat的日志编码设置;2、检查ide的编码设置;3、检查操作系统的编码设置;4、使用过滤器处理日志;5、检查外部系统的编码设置;6、检查文件编码方式等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

328

2024.02.23

weblogic和tomcat有哪些区别
weblogic和tomcat有哪些区别

weblogic和tomcat的区别:1、功能;2、性能;3、规模;4、价格;5、安全性;6、配置和管理;7、社区支持;8、集成能力;9、升级和更新;10、可靠性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

329

2024.02.23

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

561

2024.02.23

tomcat启动闪退怎么解决
tomcat启动闪退怎么解决

tomcat启动闪退的解决办法:1、检查java环境;2、检查环境变量配置;3、检查端口被占用;4、检查配置文件编码;5、检查启动时需要的配置文件;6、检查相关文件是否丢失;7、检查防火墙和杀毒软件设置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

302

2024.02.23

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

20

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 12万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn