Springboot如何实现接口重试

embedded/2024/10/15 19:14:09/

一、前言
在实际项目中,往往在某些特定的场景下,我们需要实现接口调用异常的重试机制,比如在跨平台的业务中,需要调用第三方接口实现某些功能,难免会遇到一些网络问题,这时候需要加入重试机制了。

二、如何实现?
第一种:基于spring retry实现的重试。
1.引入maven依赖

<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId>
</dependency>

2.编写重试配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;@Configuration
@EnableRetry
public class RetryConfig {@Beanpublic RetryTemplate retryTemplate() {RetryTemplate retryTemplate = new RetryTemplate();// 设置重试策略SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();// 最大重试次数retryPolicy.setMaxAttempts(3); retryTemplate.setRetryPolicy(retryPolicy);// 设置重试间隔FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();// 重试间隔(毫秒)backOffPolicy.setBackOffPeriod(1000); retryTemplate.setBackOffPolicy(backOffPolicy);return retryTemplate;}
}

3.定义一个服务类,编写需要重试的方法

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;@Service
public class RetryService {@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))public void callApiMethod() {// 这里编写调用外部API的代码// 如果调用失败会自动重试,最多重试3次,间隔1秒}
}

4.可以配置重试监听器
如果想在重试发生时执行特定操作,可以添加一个实现了RetryListener接口的监听器类,并在RetryTemplate中设置该监听器。

import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.listener.RetryListenerSupport;
import org.springframework.stereotype.Component;@Component
public class MyRetryListener extends RetryListenerSupport {@Overridepublic <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {System.out.println("重试发生,异常信息为:" + throwable.getMessage());// 在这里可以记录日志或执行其他操作super.onError(context, callback, throwable);}
}

接着在RetryTemplate中注册这个监听器。

@Configuration
@EnableRetry
public class RetryConfig {@Autowiredprivate MyRetryListener myRetryListener;@Beanpublic RetryTemplate retryTemplate() {RetryTemplate retryTemplate = new RetryTemplate();RetryTemplate retryTemplate = new RetryTemplate();// 设置重试策略SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();// 最大重试次数retryPolicy.setMaxAttempts(3); retryTemplate.setRetryPolicy(retryPolicy);// 设置重试间隔FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();// 重试间隔(毫秒)backOffPolicy.setBackOffPeriod(1000); retryTemplate.setBackOffPolicy(backOffPolicy);// 注册重试监听器retryTemplate.registerListener(myRetryListener);return retryTemplate;}
}

最后调用重试方法。

@Service
public class RetryService {@Autowiredprivate RetryTemplate retryTemplate;public void invokeApiWithRetry() {retryTemplate.execute(context -> {callApiMethod();return null;});}@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))private void callApiMethod() {// 调用外部API的代码}
}

这时候调用失败时会重试,并且在重试发生出发监听,打印相应的异常日志。

第二种:使用网络工具的内置重试机制。
比如我们使用Apche HttpClient调用第三方接口时,它其实内置了相关的重试机制
在5.x的版本时:

 CloseableHttpClient httpClient = HttpClients.custom().setRetryStrategy(new DefaultHttpRequestRetryStrategy(3,NEG_ONE_SECOND)).build();

在上面的示例代码中,我们使用DefaultHttpRequestRetryStrategy来创建一个重试机制,最大重试次数为3次。如果请求失败,则会自动重试。

当然:Apache HttpClient还支持自定义重试策略,我们可以根据需要,通过实现RetryStrategy接口,自定义重写逻辑,如下:

CloseableHttpClient httpClient = HttpClients.custom().setRetryStrategy((response, executionCount, context) -> {if (executionCount > 3) {// 如果重试次数超过3次,则放弃重试return false;}int code = response.getCode();if (code >= 500 && code < 600) {// 如果遇到服务器错误状态码,则进行重试return true;}// 其他情况不进行重试return false;}) .build();

总结:
在请求重试的时候,我们也要注意一些关键点,以免因为重试,引发更多的问题,以下这些点我们需要考虑:
1.合理设置重试次数和重试间隔时间,避免频繁地发送请求,同时也不要设置过大的重试次数,以免影响系统的性能和响应时间。

2.在使用重试机制时,需要注意不要陷入死循环。如果请求一直失败,重试次数一直增加,可能会导致系统崩溃或者资源耗尽等问题。

3.考虑接口幂等性:如果请求是写操作,那么在重试时需要谨慎处理。
在重试过程中,需要考虑接口并发的问题,如果多个线程同时进行重试,可能会导致请求重复发送或请求顺序混乱等问题。可以使用锁或者分布式锁来解决并发问题。


http://www.ppmy.cn/embedded/8690.html

相关文章

Redis如何查看KEY的数据类型

1. 查看数据类型 在Redis中&#xff0c;可以使用 TYPE 命令来查看指定key的数据类型。该命令会返回存储在指定key中的值的数据类型。以下是具体的使用方法和步骤&#xff1a; 连接到Redis服务器&#xff1a;首先&#xff0c;你需要使用Redis客户端工具&#xff08;如命令行工具…

深度学习从入门到精通—Transformer

1.绪论介绍 1.1 传统的RNN网络 传统的RNN&#xff08;递归神经网络&#xff09;主要存在以下几个问题&#xff1a; 梯度消失和梯度爆炸&#xff1a;这是RNN最主要的问题。由于序列的长距离依赖&#xff0c;当错误通过层传播时&#xff0c;梯度可以变得非常小&#xff08;消失…

boot https ssl

生成命令&#xff1a; keytool -importkeystore -srckeystore D:\sslTest.keystore -destkeystore D:\sslTest.keystore -deststoretype pkcs12keytool -genkeypair -alias "sslTestKey" -keyalg "RSA" -keystore "D:\sslTest.keystore"yml: s…

arm-day8

一、IIC总线的基本概念&#xff1a; iic总线是一种带应答的同步的、串行、半双工的通信方式&#xff0c;支持一个主机对应多个从机。 二、IIC总线的通信流程&#xff1a; 当主机向从机发送数据时&#xff1a; 1.主机需要发送一位起始位&#xff08;时钟线为高…

如何封装Vue组件并上传到npm

前言 环境准备 1.注册npm账号&#xff1a;npm | Home (npmjs.com) 2.保证当前环境安装了vue、webpack、node&#xff0c;以下工作将在该环境下进行&#xff08;没有的小伙伴自行百度安装哈~&#xff09; 3.一下用到的环境版本 webpack&#xff1a;v5.1.4node&#xff1a;v…

【nodejs】express-generator项目--创建接口及数据库连接

文章目录 一、创建接口1、路由routes&#xff08;1&#xff09;新建路由文件&#xff08;2&#xff09;注册路由 2、控制器controller&#xff08;1&#xff09;新建controller文件&#xff08;2&#xff09;代码 3、services&#xff08;1&#xff09;新建services文件&#x…

framework.jar如何导入到android studio中进行framework的开发+系统签名

framework的开发 生成framework.jar的方式 链接: framework.jar 生成 如何生成一个系统签名 链接: 生产系统签名 生成 platform.x509.pem、platform.pk8文件位置 生产系统签名 清单文件位置改变 <manifest xmlns:android"http://schemas.android.com/apk/res/a…

如何实现在 Windows 上运行 Linux 程序?

在Windows 上运行Linux程序是可以通过以下几种方法实现: 1.使用 Windows Subsystem for Linux (WSL): WSL是微软提供的功能&#xff0c;可以在Windows 10上运行一个完整的Linux系统。用户可以在Microsoft Store中安装所需的 在开始前我有一些资料&#xff0c;是我根据网友给的…