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

就可以运行查看效果了.

相关推荐
不会编程的懒洋洋21 分钟前
Spring Cloud Eureka 服务注册与发现
java·笔记·后端·学习·spring·spring cloud·eureka
赖龙26 分钟前
java程序打包及执行 jar命令及运行jar文件
java·pycharm·jar
U12Euphoria28 分钟前
java的runnable jar采用exe和.bat两种方式解决jre环境的问题
java·pycharm·jar
java小吕布1 小时前
Java Lambda表达式详解:函数式编程的简洁之道
java·开发语言
程序员劝退师_1 小时前
优惠券秒杀的背后原理
java·数据库
java小吕布1 小时前
Java集合框架之Collection集合遍历
java
一二小选手1 小时前
【Java Web】分页查询
java·开发语言
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 小时前
idea 弹窗 delete remote branch origin/develop-deploy
java·elasticsearch·intellij-idea
Code成立1 小时前
《Java核心技术 卷I》用户图形界面鼠标事件
java·开发语言·计算机外设
鸽鸽程序猿2 小时前
【算法】【优选算法】二分查找算法(下)
java·算法·二分查找算法