当前位置: 首页 > news >正文

Spring Boot 集成第三方 API 时,常见的超时与重试机制设计

在日常的Spring Boot开发中,经常需要和第三方系统进行交互,比如支付接口、短信接口、地图接口等等。

然而,第三方 API 并不是一直都稳定可用的。网络波动、服务异常、接口限流、超时未响应等情况非常常见。如果没有合理的超时与重试机制,可能导致:

  • 请求长时间阻塞,拖垮线程池;
  • 接口调用失败,直接返回错误,用户体验不佳;
  • 在支付、下单等场景中,可能出现数据不一致的问题。
    本文将结合 Spring Boot 常见的 HTTP 客户端(RestTemplate、WebClient、OpenFeign),系统性地讲解如何设置 超时与重试机制,并设计一套健壮的调用方案。

1. 常见 HTTP 客户端的超时配置

1.1. 使用 RestTemplate

  • 配置类
@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {return builder.setConnectTimeout(Duration.ofSeconds(5)).setReadTimeout(Duration.ofSeconds(5)).build();}
}
  • 使用示例
@RestController
@RequestMapping("demo")
public class DemoController {@Autowiredprivate RestTemplate restTemplate;@PostMapping("/getData1")public String getData1() {String url = "https://blog.csdn.net/weixin_54009596/article/details/151334355";return restTemplate.getForObject(url, String.class);//return restTemplate.getForEntity(url, String.class).getBody();}
}

1.2. 使用 WebClient

WebClient 是 Spring WebFlux 的非阻塞式 HTTP 客户端,比 RestTemplate 更加现代和灵活。

  • 配置类
@Configuration
public class WebClientConfig {@Beanpublic WebClient webClient(WebClient.Builder builder) {return builder// 配置了baseUrl,默认读取这个.baseUrl("https://blog.csdn.net/weixin_54009596/article/details/151334355").clientConnector(new ReactorClientHttpConnector(HttpClient.create().responseTimeout(Duration.ofSeconds(10)) // 响应超时.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 连接超时)).build();}
}
  • 使用示例
@RestController
@RequestMapping("demo")
public class DemoController {@Autowiredprivate WebClient webClient;@PostMapping("/getData2")public Mono<String> getData2() {return webClient.get().uri("/151334355")    //拼上配置中的url.retrieve().bodyToMono(String.class);}
}

WebClient 在高并发场景下比 RestTemplate 更有优势。

1.3. 使用 OpenFeign

  • 配置超时
feign:client:config:default:connectTimeout: 5000   # 连接超时readTimeout: 10000     # 读取超时
  • 使用示例
@FeignClient(name = "thirdApi", url = "https://blog.csdn.net/weixin_54009596/article/details/151334355")
public interface ThirdPartyClient {@GetMapping("/data")String getData();
}

2. 重试机制设计

2.1. 使用 Spring Retry

Spring 提供了 spring-retry 组件,可以优雅地实现重试。

  • 引入依赖
<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId>
</dependency>
  • 启动类上加@EnableRetry注解

  • 使用

@Service
@Slf4j
public class DemoService {@Autowiredprivate RestTemplate restTemplate;@Retryable(value = { SocketTimeoutException.class, IOException.class },maxAttempts = 3, backoff = @Backoff(delay = 10000, multiplier = 2))public String getData1() {String url = "https://blog.csdn.net/weixin_54009596/article/details/151334355";try {return restTemplate.getForEntity(url, String.class).getBody();} catch (Exception e) {return recover(e);}}@Recoverpublic String recover(Exception e) {log.error("调用失败,进入降级逻辑1: {}", e.getMessage());return"fallback response";}
}

说明:
@Retryable:指定异常重试,最大尝试次数,延迟时间;
@Backoff:支持指数退避,避免短时间内的频繁请求;
@Recover:定义最终失败时的降级逻辑。

2.2. 使用 Resilience4j 实现重试 + 熔断

更强大的选择是 Resilience4j,支持 重试、熔断、限流、隔离舱。

  • 引入依赖
 <dependency><groupId>io.github.resilience4j</groupId><artifactId>resilience4j-spring-boot2</artifactId><version>1.7.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
  • 配置
resilience4j.retry:instances:apiRetry:max-attempts: 3wait-duration: 2sretry-exceptions:- java.io.IOException- java.net.SocketTimeoutException
  • 使用
@Service
@Slf4j
public class DemoService {@Autowiredprivate RestTemplate restTemplate;@Retry(name = "apiRetry", fallbackMethod = "fallback")public String getData1() {String url = "https://blog.csdn.net/weixin_54009596/article/details/151334355";return restTemplate.getForEntity(url, String.class).getBody();}public String fallback(Exception e) {log.error("调用失败,进入降级逻辑2: {}", e.getMessage());return"fallback response";}
}

文章转载自:

http://pcZCK8v4.bnfsw.cn
http://w8zxdoe5.bnfsw.cn
http://V6p7pMHO.bnfsw.cn
http://muTN72ZA.bnfsw.cn
http://5iLVsjLj.bnfsw.cn
http://jAs0Hkod.bnfsw.cn
http://eU1KxbBD.bnfsw.cn
http://SLPMrdVU.bnfsw.cn
http://juKh0CIH.bnfsw.cn
http://ft13CzlB.bnfsw.cn
http://QyxDklZQ.bnfsw.cn
http://B9jzJkfu.bnfsw.cn
http://KuGZdmN3.bnfsw.cn
http://apEoXoYp.bnfsw.cn
http://pL2b1qHZ.bnfsw.cn
http://Sg3G8xog.bnfsw.cn
http://GzPaqYKt.bnfsw.cn
http://5SJhMYC1.bnfsw.cn
http://0Sa4Vr43.bnfsw.cn
http://faeZmRBs.bnfsw.cn
http://810zaAVN.bnfsw.cn
http://8k4IMQYj.bnfsw.cn
http://8tUDGhEf.bnfsw.cn
http://bUVszBmr.bnfsw.cn
http://pjEFY2da.bnfsw.cn
http://zEhdP1w6.bnfsw.cn
http://1Oqg3woi.bnfsw.cn
http://xP2xz6iy.bnfsw.cn
http://wWE9W7ZC.bnfsw.cn
http://JKBtdy14.bnfsw.cn
http://www.dtcms.com/a/383630.html

相关文章:

  • 设计模式——创建型模式
  • Nginx_Tomcat综合案例
  • Java常见类类型与区别详解:从实体类到异常类的全面指南
  • MOS管驱动栅极出现振铃现象
  • camke中采用vcpkg工具链设置OSG时
  • 玩转ElasticSearch
  • 设计模式-模板模式详解
  • GDB调试技巧实战--揪出内存泄漏元凶
  • LLM基础-工程化
  • Ubuntu系统下交叉编译Android的Lame库
  • AI 重构医疗:辅助诊断、药物研发、健康管理的三大落地场景实践
  • MySQL的日志系统(redolog、binlog、WAL技术)
  • 贪心算法应用:半导体晶圆生产问题详解
  • 按键精灵解决重复性点击
  • 索引-分类
  • webrtc弱网-IntervalBudget类源码分析与算法原理
  • 第20课:数据治理与合规
  • 模型训练中的数据泄露:原理解析与实战防范指南
  • 凌晨0-3点不睡,你熬的不是夜,是人生!
  • [哈希表]966. 元音拼写检查器
  • 密码库的轻量化定制裁剪:技术原理与实践指南
  • Tomcat vs JBoss:轻量级与重型Java服务器对比
  • v-model与-sync的演变和融合
  • Vue的快速入门
  • 26考研——进程与线程(2)
  • Java基础 9.14
  • Node.js核心模块介绍
  • 认识集合框架
  • DMA 控制器核心组件作用与使用解读
  • 卫星通信天线的指向精度,含义、测量和计算