Spring Cloud: OpenFeign 超时重试机制

超时重试是一种用于网络通信的常用策略,目的是在请求未能在规定时间内获得响应或响应超时的情况下,重新发送请求。具体来说,当发起请求后,如果在设定的时间内未能收到预期的响应,就会启动超时重试机制,重新发送该请求。超时重试的主要目标是提高请求的可靠性和稳定性,以应对网络不稳定、服务不可用、响应延迟等情况。

简单来说,超时重试就像是给网络请求设置了一个"保底方案"。假设你在网上购物时提交了一个订单请求,但由于网络原因,这个请求没有及时得到响应。超时重试机制就会在一定时间内再次发送这个请求,直到成功或者达到最大重试次数为止。

举个例子,想象一下你正在给朋友发信息,但发出去后没有收到"已读"回执,你可能会等一会儿再重新发送这条信息。超时重试机制就是这样一个过程,但它是自动完成的,不需要人工干预。这个机制能提高请求的成功率,确保在网络不稳定或者服务暂时不可用时,系统仍能保持较高的可靠性和稳定性。

通过这种方式,即使网络出现短暂的问题,用户的请求也能在多次尝试后最终成功,大大提升了用户体验和系统的健壮性。

在微服务架构中,服务之间通过网络进行通信,而网络环境往往具有复杂性和不稳定性。因此,在调用服务时可能会出现失败或超时的情况。为了解决这些问题,Spring Cloud OpenFeign 提供了超时重试机制。

OpenFeign 超时重试步骤

  1. 设置OpenFeign超时时间 (设置完才能实现超时功能, 有了超时功能才能完成重试操作)
  • 请求最大连接时间
  • 读取时间
  1. 进行重试操作.(重试功能)
  • 重试次数
  • 重试间隔时间
  • 最大间隔时间

前文示例回顾

以上文项目示例为例, 项目中有两个模块, 一个是生产者 provider, 一个是消费者 consumer.

生产者 provider 提供了 getnamebyid 服务, 该服务对于 consumer 来说是一个远程服务(多模块, 微服务), 也就是该接口是一个远程接口.

消费者 consumer 则使用 OpenFeign + Loadbalancer + Nacos 进行调用:

在 consumer 里面会有一个 service, 在 service 里面使用了 OpenFeign 调用了 nacos-discovery-demo 的服务, 在服务中请求了远程接口 /user/getnamebyid, 得到了一个响应结果, 然后对它进行展示.

OpenFeign 超时重试配置

OpenFeign 默认情况下是不会自动开启超时重试的,所以想要开启超时重试,需要通过以下 2 步来实现:

  1. 配置超时重试
  2. 覆盖 Retryer 对象

配置服务消费者超时时间

bash 复制代码
spring:
  application:
    name: nacos-consumer-demo
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
        register-enabled: false
    openfeign:
      client:
        config:
          default:
            connect-timeout: 1000 # 连接超时时间
            read-timeout: 1000 # 读取超时时间
server:
  port: 8080

开启超时重试

在IoC容器注入Retry对象, 使用的时候new即可.

java 复制代码
package org.example.consumer.config;

import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RetryConfig {
    @Bean
    public Retryer retryer() {
        return new Retryer.Default(
                1000,       // 重试间隔时间
                1000,       // 最大重试间隔时间
                3           // 最大重试次数
        );     
    }
}

示例代码

在provider中加入, 使服务超时的代码:

在消费者中配置超时重试:

启动生产者与消费者, 然后访问 getnamebyid 接口, 可以看到超时异常:

自定义超时重试机制

自定义超时重试机制的实现分为以下两步:

  1. 自定义超时重试类(实现 Retryer 接口,并重写 continueOrPropagate 方法)
  2. 设置配置文件。

创建一个超时重传的类

实现 Retryer 接口并重写 continueOrPropagate 方法

java 复制代码
package org.example.consumer.config;

import feign.RetryableException;
import feign.Retryer;

import java.time.LocalDateTime;

public class CustomRetryer implements Retryer {
    private final int maxAttempts;  // 最大尝试次数
    private final long backoff;  // 超时间隔时间
    int attempt;    // 当前尝试次数

    public CustomRetryer() {
        this.maxAttempts = 3;
        this.backoff = 1000L;
        this.attempt = 0;
    }

    @Override
    public void continueOrPropagate(RetryableException e) {
        if (attempt++ >= maxAttempts) {
            throw e;
        }
        long interval = this.backoff;
        System.out.println(LocalDateTime.now() + " | 执行一次重试: " + interval);
        try {
            Thread.sleep(interval * attempt);
        } catch (InterruptedException ex) {
            throw new RuntimeException(ex);
        }

    }

    @Override
    public Retryer clone() {
        return new CustomRetryer();
    }
}

将自定义类设置到配置文件中

将自定义超时重传类设置到配置文件 OpenFeign... retryer 属性中

就可以运行查看效果了.

相关推荐
科技资讯早知道10 分钟前
java计算机毕设课设—坦克大战游戏
java·开发语言·游戏·毕业设计·课程设计·毕设
小比卡丘1 小时前
C语言进阶版第17课—自定义类型:联合和枚举
android·java·c语言
xmh-sxh-13141 小时前
java 数据存储方式
java
liu_chunhai1 小时前
设计模式(3)builder
java·开发语言·设计模式
ya888g2 小时前
GESP C++四级样题卷
java·c++·算法
【D'accumulation】2 小时前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端
小叶学C++2 小时前
【C++】类与对象(下)
java·开发语言·c++
2401_854391082 小时前
高效开发:SpringBoot网上租赁系统实现细节
java·spring boot·后端
王彬泽2 小时前
【微服务】组件、基础工程构建(day2)
微服务
Cikiss2 小时前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务