课程网站开发流程图及原型图,高手做网站,龙港做网页网站制作,手机上如何开发软件请求三方接口需要加入重试机制 一、循环重试
在请求接口的代码块中加入循环#xff0c;如果请求失败则继续请求#xff0c;直到请求成功或达到最大重试次数。
int retryTimes 3;
for(int i 0;i retryTimes;i){try{//请求接口的代码break;}catch(Exception e){//处理…请求三方接口需要加入重试机制 一、循环重试
在请求接口的代码块中加入循环如果请求失败则继续请求直到请求成功或达到最大重试次数。
int retryTimes 3;
for(int i 0;i retryTimes;i){try{//请求接口的代码break;}catch(Exception e){//处理异常Thread.sleep(1000);//为了避免频繁请求,延迟1秒后重试}
}二、使用递归结构
在请求接口的方法中调用自身如果请求失败则继续调用直到请求成功或达到最大重试次数。
public void requestWithRetry(int retryTimes){if(retryTimes 0){return;}try{//请求接口的代码}catch(Exception e){//处理异常Thread.sleep(1000);//延迟1秒后重试requestWithRetry(retryTimes - 1);}
}三、使用网络工具内置重试机制
HTTP 客户端通常内置了一些重试机制只需要在创建对应的客户端实例的时候进行配置即可以 Apache HTTPClient 为例
4.5 版本使用 HttpClients.custom().setRetryHandler() 方法来设置重试机制5.x 版本使用 HttpClients.custom().setRetryStrategy() 方法来设置重试机制
CloseableHttpClient httpClient HttpClients.custom().setRetryHandler(new DefaultHttpRequestRetryHandler(3,true)).build();CloseableHttpClient httpClient HttpClients.custom().setRetryStrategy(new DefaultHttpRequestRetryStrategy(3,NEG_ONE_SECOND)).build();Apache HTTPClient 还支持自定义重试策略可以可以实现 HTTPRequestRetryHandler 接口4.5 版本或者 RetryStrategy 接口5.x 版本
CloseableHttpClient httpClient HttpClients.custom().setRetryStrategy((response,executionCount,context) - {if(executionCount 3){//如果重试次数超过3次则放弃重试return false;}if(status 500 statusCode 600){//如果遇到服务器错误状态码则进行重试return true;}//其他情况不进行重试return false;}).build();四、使用Spring Retry库
Spring Retry 提供了一组注解和工具类可以方便地为方法添加重试功能。
dependencygroupIdorg.springframework.retry/groupIdartifactIdspring-retry/artifactIdversion1.3.1/version
/dependencySpring Retry 的使用有两种方式一种是使用 RetryTemplate 来显式调用需要重试的方法一种实用注解来自动触发重试。
显式调用
RetryTemplate retryTemplate new RetryTemplate();//配置重试策略
RetryPolicy retryPolicy new SimpleRetryPolicy(3);
retryTemplate.setRetryPolicy(retryPolicy);//最大重试次数为 3 次//配置重试间隔策略
FixedBackOffPolicy backOffPolicy new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(1000);//重试间隔为 1 秒
retryTemplate.setBackOffPolicy(backOffPolicy);//使用RetryTemplate调用方法执行需要重试的代码块
retryTemplate.execute((RetryCallbackVoid,Exception) context - {//请求接口的代码return null;
});Spring Retry 是一个提供重试机制的库可以方便地在 Spring 项目中使用。使用 Retryable 注解标记需要重试的方法如果方法抛出异常则会自动重试。
Retryable(valueException.class,maxAttempts3)
public void request(){//请求接口的代码
}注解调用
①、配置重试切面
Configuration
EnableRetry //启用重试功能
public class RetryConfig{//配置其他bean
}②、注解标记需要重试的方法
Retryable(maxAttempts3)//指定了最大重试次数为 3 次
public void request(){//请求接口代码
}③、调用被标记的方法
Autowired
private HttpService httpService;httpService.request();springboot中使用
①、启动类开启 Spring Retry 功能
SpringBootApplication
EnableRetry // 启用Spring Retry功能
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}②、进行重试的方法上添加 Retryable指定了重试的异常类型、最大重试次数和重试间隔 Backoff 注解用于指定重试间隔策略delay 属性表示每次重试之间的间隔时间。在这个例子中每次重试之间的间隔时间为 1 秒 Retryable 注解只能标记在 public 方法上。如果需要在非 public 方法上使用重试功能可以使用代理模式实现
Service
public class MyService {Retryable(value {MyException.class}, maxAttempts 3, backoff Backoff(delay 1000))public void doSomething() {// 需要进行重试的方法逻辑}
}如果需要在重试过程中进行一些特定的操作比如记录日志、发送消息等可以在重试方法中使用 RetryContext 参数它提供了一些有用的方法来获取重试的上下文信息。
Service
public class MyService {Retryable(value {MyException.class}, maxAttempts 3, backoff Backoff(delay 1000))public void doSomething(RetryContext context) {// 获取重试次数int retryCount context.getRetryCount();// 获取上一次异常Throwable lastThrowable context.getLastThrowable();// 记录日志、发送消息等操作// ...// 需要进行重试的方法逻辑}
}五、使用Resilience4j库
提供了重试、熔断、限流等多种机制 dependencygroupIdio.github.resilience4j/groupIdartifactIdresilience4j-spring-boot2/artifactIdversion1.7.0/version
/dependency1、显式调用
//创建一个 RetryRegistry 对象
RetryRegistry retryRegistry RetryRegistry.ofDefalults();//配置RetryRegistry实例,使用 RetryConfig 类来自定义 Retry 的配置包括最大重试次数、重试间隔等
RetryConfig config RetryConfig.custom().maxAttempts(3)//最大重试次数为 3 次.waitDuration(Duration.ofMillis(1000))//重试间隔为 1 秒.retryOnResult(response - response.getStatus() 500)//返回结果的状态码为 500 时进行重试.retryOnException(e - e instanceof WebServiceException)//抛出 WebServiceException 异常时进行重试.retryExceptions(IOException.class, TimeoutException.class).ignoreExceptions(BusinessException.class, OtherBusinessException.class)//忽略 BusinessException 和 OtherBusinessException 异常.failAfterMaxAttempts(true).build();//使用 Retry 来装饰和执行需要进行重试的代码块
CheckedFunction0String retryableSupplier Retry.decorateCheckedSupplier(retry, () - {// 需要进行重试的代码return result;
});2、注解调用
//SpringBoot项目中使用Retryable注解来标记需要重试的方法
Service
public class MyService{//指定了重试的异常类型为MyException最大重试次数3次重试间隔1秒Retryable(value{MyException.class},maxAttempts3,backoffBackoff(delay 1000))public void doSomething(){//需要进行重试的方法逻辑}
}六、自定义重试工具类
①、自定义一个是实现了Callback抽象类的具体回调类
public abstract class Callback{//执行重试逻辑public abstract RetryResult doProcess();//RetryResult封装重试结果
}②、封装重试结果
public class RetryResult{private Boolean isRetry;//是否需要进行重试private Object obj;//重试的结果对象//构造方法和getter方法省略public static RetryResult ofResult(Boolean isRetry, Object obj){return new RetryResult(isRetry, obj);}public static RetryResult ofResult(Boolean isRetry){return new RetryResult(isRetry, null);}
}③、执行
public class RetryExecutor{//接收一个重试次数和一个回调对象public static Object execute(int retryCount,Callback callback){for(int curRetryCount 0;curRetryCount retryCount;curRetryCount){RetryResult retryResult callback.doProcess();if(retryResult.isRetry()){continue;}return retryResult.getObj();}return null;}
}使用这个自定义的重试工具类时只需要实现一个继承自 Callback 的回调类并在其中实现具体的重试逻辑。然后通过调用 RetryExecutor.execute() 方法来执行重试操作。这里直接用了一个匿名的实现
//最大重试次数
int maxRetryCount 3;
Object result RetryExecutor.execute(maxRetryCount, new Callback() {Overridepublic RetryResult doProcess() {// 执行需要重试的逻辑// 如果需要重试返回 RetryResult.ofResult(true)// 如果不需要重试返回 RetryResult.ofResult(false, result)}
});七、并发框架异步重试
使用ThreadPoolExecutor把请求接口转换成一个异步任务将任务放入线程池中异步执行 并发地重试请求接口。 可以在任务执行完成后判断任务执行结果如果失败则继续重试
int maxRetryTimes 3;
int currentRetryTimes 0;ThreadPoolExecutor executor new ThreadPoolExecutor(10,//核心线程数10,//最大线程数0L,//空闲线程存活时间TimeUnit.MILLISECONDS,//时间的单位new LinkedBlockingQueue()//任务队列
);//任务
CallableString task () - {//请求接口的代码return result;
}FutureString future;
while(currentRetryTimes maxRetryTimes){try{future executor.submit(task);String result future.get();//获取任务结果//判断任务执行结果如果任务执行成功则跳出循环如果任务执行失败则继续重试直到达到最大重试次数break;}catch(Exception e){currentRetryTimes;try{Thread.sleep(1000);}catch(InterruptedException ex){Thread.currentThread().interrupt();}}
}八、消息队列重试
保证重试的可靠性不会因为服务中断而导致重试任务的丢失可以引入消息队列 直接把消息投递到消息队列里通过对消息的消费来实现重试机制。
//指定了消费者的相关配置包括消费者组和订阅的主题
Component
RocketMQMessageListener(topicmyTopic,consumerGroupmyConsumerGroup)
public class MyConsumer implements RocketMQListenerString{Overridepublic void onMessage(String message){try{//请求接口的代码}catch(Exception e){//处理异常//如果请求失败创建一个 RocketMQ 的生产者并将请求重新发送到消息队列中等待下一次处理DefaultMQProducer producer new DefaultMQProducer(myProducerGroup);producer.setNamesrvAddr(127.0.0.1:9876);try{producer.start();}catch(Exception ex){//处理异常}finally{producer.shutdown();}}}
}【注意】
合理设置重试次数和重试间隔时间避免频繁地发送请求同时也不要设置过大的重试次数以免影响系统的性能和响应时间。考虑接口幂等性如果请求是写操作而且下游的服务不保证请求的幂等性那么在重试时需要谨慎处理可以通过查询等幂等的方式进行重试在重试过程中需要考虑并发的问题。如果多个线程同时进行重试可能会导致请求重复发送或请求顺序混乱等问题。可以使用锁或者分布式锁来解决并发问题。在处理异常时需要根据具体的异常类型来进行处理。有些异常是可以通过重试来解决的例如网络超时、连接异常等而有些异常则需要进行特殊的处理例如数据库异常、文件读写异常等。在使用重试机制时需要注意不要陷入死循环。如果请求一直失败重试次数一直增加可能会导致系统崩溃或者资源耗尽等问题。