提升性能!使用Reactor合并三方接口请求

文摘   2024-11-14 19:00   新疆  

最新实战案例锦集:《Spring Boot3实战案例合集》持续更新,每天至少更新一篇文章,订阅后将赠送文章最后展示的所有MD文档(学习笔记)。

环境:SpringBoot3.2.5



1. 简介

在项目开发中,经常需要从多个第三方接口获取数据以完成复杂的业务逻辑。传统的同步请求方式不仅效率低下,还可能导致用户界面卡顿,影响用户体验。本文深入探讨了如何利用Reactor框架的强大能力,实现异步非阻塞的编程模型,有效合并并处理多个第三方接口请求。通过Reactor的Mono核心组件,我们可以实现请求的并行处理、智能的背压机制以及高效的资源利用,从而在不影响系统稳定性的前提下,显著提升数据获取与处理的效率。

Reactor 是一个响应式编程库,提供了 Mono 和 Flux 两种数据类型来处理异步操作和数据流。通过使用 Mono 和 Flux,我们可以在不阻塞主线程的情况下并发地调用多个第三方接口,并在所有请求完成后合并结果。这种方式不仅提高了系统的吞吐量,还减少了用户的等待时间。

例如,假设我们需要从三个不同的 API 获取用户积分信息、库存信息和优惠券信息。在使用JDK自带的 CompletableFuture 实现有如下一些问题:

  1. 阻塞调用

  2. CompletableFuture 的 get 方法是阻塞的,这意味着在等待结果时会阻塞当前线程。虽然可以使用 thenApply 等非阻塞方法,但在处理多个异步任务时,仍然需要小心避免不必要的阻塞。

  3. 错误处理

  4. 错误处理相对复杂。虽然可以使用 exceptionally 方法处理异常,但在组合多个异步任务时,错误传播和处理变得较为繁琐。

  5. 资源管理

  6. 默认使用 ForkJoinPool.commonPool(),在高并发场景下可能会导致线程池资源耗尽。需要手动管理线程池,增加了复杂性。

  7. 响应式支持

  8. CompletableFuture 主要用于传统的异步编程,缺乏对响应式流规范的支持。相比之下,Mono 和 Flux 充分支持响应式编程模型,提供了更丰富的操作符和更灵活的错误处理机制。


而对于 Reactor 提供了丰富的错误处理和重试机制,确保在请求失败时能够优雅地处理异常情况。通过合理配置连接池和超时时间,我们可以进一步优化系统的资源利用率,提高系统的稳定性和可靠性。

接下来,我们通过实例代码来讲解使用 Reactor Mono + WebClient实现三方接口调用的合并处理。

2. 实战案例

2.1 准备三方接口

@GetMapping("/users/{userId}")public String getScore(@PathVariable String userId) {  try {    TimeUnit.SECONDS.sleep(1) ;  } catch (InterruptedException e) {}  return String.format("用户【%s】500积分", userId) ;}
@GetMapping("/stocks/{productId}")public String getStock(@PathVariable String productId) { try { TimeUnit.SECONDS.sleep(2) ; } catch (InterruptedException e) {} return String.format("商品【%s】500件", productId) ;}
@GetMapping("/coupons/{userId}")public String getCoupons(@PathVariable String userId) { try { TimeUnit.SECONDS.sleep(3) ; } catch (InterruptedException e) {} return String.format("用户拥有【%s】6张优惠卷", userId) ;}

以上代码分别通过sleep模拟耗时操作。

Spring全家桶实战案例源码
spring, springboot, springcloud 案例开发详解
 最新文章