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 属性中

就可以运行查看效果了.

相关推荐
Pluchon8 分钟前
硅基计划3.0 Map类&Set类
java·开发语言·数据结构·算法·哈希算法·散列表
Angelyb31 分钟前
微服务保护和分布式事务
java·微服务·架构
鼠鼠我捏,要死了捏32 分钟前
蓝绿发布与滚动更新:基于Kubernetes的微服务零停机切换实战指南
微服务·kubernetes·blue-green
七夜zippoe39 分钟前
缓存三大劫攻防战:穿透、击穿、雪崩的Java实战防御体系(一)
java·开发语言·缓存
帧栈1 小时前
开发避坑指南(46):Java Stream 对List的BigDecimal字段进行求和
java
重生之我是Java开发战士1 小时前
【数据结构】Java集合框架:List与ArrayList
java·数据结构·list
爱干饭的boy2 小时前
手写Spring底层机制的实现【初始化IOC容器+依赖注入+BeanPostProcesson机制+AOP】
java·数据结构·后端·算法·spring
影子24012 小时前
java jdbc连接sqlserver2008R2版本数据库报错,驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接
java·数据库·ssl
失散132 小时前
分布式专题——10.1 ShardingSphere介绍
java·分布式·架构·shardingsphere·分库分表
记得开心一点嘛2 小时前
手搓Tomcat
java·tomcat