掌握OpenFeign-3:OpenFeign 高级配置㊗️

该文章已生成可运行项目,

📖 主要讲解 - 重试机制   Fallback 机制 

🗣️-简介      


        OpenFeign 是一个声明式的 HTTP 客户端,它简化了 REST API 的调用过程。但在复杂的生产环境中,高级配置变得至关重要,以下是使用OpenFeign 高级配置的主要原因其中之一比如:

提升调用性能和稳定性:

  • 重试机制💫 :配置请求失败时的重试策略,提高系统在短暂网络故障中的容错能力。
  • Fallback 机制 🚀:远程服务不可用时提供备用逻辑,确保系统的健壮性和可用性。

🧠-学习目的

这篇文章我们将探讨OpenFeign 高级配置🔥 ,我们希望达成以下具体的目标: 

  1. ✅重试机制:理解如果请求失败,怎么使用重试机制预设的策略重新尝试发送请求 。
  2. ✅Fallback机制:理解远程服务不可用时如何提供备用逻辑。

💫-重试机制 

1️⃣-原理介绍

         OpenFeign 客户端向远程服务发送请求时,如果请求失败(例如由于网络连接中断、超时、服务端返回错误状态码等原因),重试机制会根据预设的策略重新尝试发送请求

2️⃣-核心作用

  • 容错保障:在网络波动、服务短暂不可用(如超时、5xx错误)时,通过自动重试提升系统可用性。
  • 异常触发:默认针对IOException(如连接超时、SocketException)触发重试,非所有异常(如4xx错误通常不重试)。

  

3️⃣-默认重试策略

重试器Retryer.Default。

  • 最大重试次数:3次(首次请求 + 3次重试 = 最多4次调用)。
  • 退避策略:间隔时间逐步递增(避免雪崩效应),公式近似为间隔 = 100ms * (1 + 重试次数)

4️⃣-适用场景示例

  • 电商系统案例:订单服务调用库存服务时,若因网络抖动导致超时,OpenFeign自动重试,避免业务中断。
  • 关键场景:读操作(如查询库存)、幂等写操作(如GET/PUT);非幂等操作(如POST)需谨慎启用。

5️⃣-自定义重试器

         在实际应用中,有时默认的重试策略可能无法满足业务需求,这时就需要自定义重试器。定义自定义重试器可以通过实现Retryer接口或继承RetryTemplate类来实现。example如下:

 

5.1-实现 Retryer 接口
import feign.Retryer;

public class CustomRetryer implements Retryer {
    private int maxAttempts = 5; // 最大重试次数
    private long period = 1000; // 初始重试间隔时间,单位毫秒
    private long maxPeriod = 5000; // 最大重试间隔时间,单位毫秒
    private int attempt = 1;

    @Override
    public void continueOrPropagate(RetryableException e) {
        if (attempt++ >= maxAttempts) {
            throw e;
        }
        long interval;
        if (e.retryAfter() != null) {
            interval = e.retryAfter().getTime() - System.currentTimeMillis();
            if (interval > maxPeriod) {
                interval = maxPeriod;
            }
            if (interval < 0) {
                return;
            }
        } else {
            interval = nextMaxInterval();
        }
        try {
            Thread.sleep(interval);
        } catch (InterruptedException ignored) {
            Thread.currentThread().interrupt();
            throw e;
        }
    }

    private long nextMaxInterval() {
        long interval = (long) (period * Math.pow(1.5, attempt - 1));
        return interval > maxPeriod? maxPeriod : interval;
    }

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

         在上述代码中,CustomRetryer实现了Retryer接口,并重写了continueOrPropagate和clone方法。continueOrPropagate方法中定义了重试的逻辑,根据当前重试次数和最大重试次数进行判断,如果超过最大重试次数则抛出异常;否则,根据retryAfter或自定义的算法计算重试间隔时间,并让线程休眠相应时间。nextMaxInterval方法用于计算下一次重试的间隔时间,这里采用了指数增长的方式,避免重试过于频繁。

5.2-继承 RetryTemplate 类
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.support.RetryTemplate;

public class CustomRetryTemplate extends RetryTemplate {
    public CustomRetryTemplate() {
        // 设置重试策略
        setRetryPolicy(new SimpleRetryPolicy(5, 1000)); // 重试5次,每次间隔1秒
    }

    @Override
    public <T> T execute(RetryCallback<T, Exception> retryCallback) throws Exception {
        return super.execute(retryCallback, new DefaultRecoveryCallback<>());
    }

    @Override
    public <T> T execute(RetryCallback<T, Exception> retryCallback, RetryContext context) throws Exception {
        return super.execute(retryCallback, context);
    }

    @Override
    public <T> T execute(RetryCallback<T, Exception> retryCallback, RetryContext context, RecoveryCallback<T> recoveryCallback) throws Exception {
        return super.execute(retryCallback, context, recoveryCallback);
    }
}

         在这个示例中,CustomRetryTemplate继承自RetryTemplate类,并在构造函数中设置了自定义的重试策略,这里设置为重试 5 次,每次间隔 1 秒。同时,根据需要重写了execute方法,以满足特定的业务需求。

5.3-注册自定义重试器

        在 Spring 配置类中注册自定义重试器。

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

@Configuration
public class FeignRetryConfig {
    @Bean
    public Retryer customRetryer() {
        return new CustomRetryer();
    }
}

 

5.4-使用自定义重试器

        在@FeignClient注解的配置类中,将自定义的重试器添加到配置中

import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(name = "stock", configuration = FeignRetryConfig.class)
public interface StockFeignClient {
    @GetMapping("/stock")
    String getStock();
}

通过以上步骤,就可以实现自定义的重试机制,以适应不同的业务场景和需求。

🚑-Fallback 机制

1️⃣-Fallback原理

        在 OpenFeign 中,Fallback 机制用于在远程服务不可用时提供备用逻辑,确保系统的健壮性和可用性。 

2️⃣-核心作用

  • 服务降级:当远程服务调用失败(如超时、熔断、异常)时,提供备用逻辑(Fallback),避免级联故障,保障系统可用性。
  • 用户体验:返回默认值、缓存数据或友好提示,而非直接抛出异常。

3️⃣-实现方式 

        定义 Fallback 类的方法是创建一个实现 Feign 客户端接口的类,并使用@Component注解将其注册为 Spring Bean。这个类将包含在远程服务调用失败时执行的备用逻辑。

         假设我们有一个StockFeignClient接口用于调用库存服务:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "stock")
public interface StockFeignClient {
    @GetMapping("/stock")
    String getStock();
}

        对应的 Fallback 类可以这样定义: 

import org.springframework.stereotype.Component;

@Component
public class StockFeignClientFallback implements StockFeignClient {
    @Override
    public String getStock() {
        // 备用逻辑,例如返回一个默认值或错误提示信息
        return "Stock service is unavailable";
    }
}

        在上述代码中,StockFeignClientFallback类实现了StockFeignClient接口,并实现了其中的getStock方法。在getStock方法中,定义了备用逻辑,当远程的库存服务不可用时,将返回 "Stock service is unavailable",而不是抛出异常,从而保证系统的其他部分能够继续正常运行。  

 

4️⃣-配置 Fallback

        配置 Fallback 是使 Fallback 机制生效的重要环节,主要有两种方式,即在@FeignClient注解中指定fallback属性和使用fallbackFactory属性。

指定 fallback 属性

        在@FeignClient注解中使用fallback属性,直接指向 Fallback 类。

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "stock", fallback = StockFeignClientFallback.class)
public interface StockFeignClient {
    @GetMapping("/stock")
    String getStock();
}

        通过上述配置,当调用StockFeignClient接口的方法失败时,会自动调用StockFeignClientFallback类中对应的方法,执行备用逻辑。

使用 fallbackFactory 属性

        如果需要访问导致 Fallback 触发的异常原因,可以使用fallbackFactory属性。首先定义一个 Fallback 工厂类:

import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

@Component
public class StockFeignClientFallbackFactory implements FallbackFactory<StockFeignClient> {
    @Override
    public StockFeignClient create(Throwable cause) {
        return new StockFeignClient() {
            @Override
            public String getStock() {
                // 根据异常原因执行不同的备用逻辑
                return "Error occurred: " + cause.getMessage();
            }
        };
    }
}

        然后在@FeignClient注解中指定fallbackFactory属性:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "stock", fallbackFactory = StockFeignClientFallbackFactory.class)
public interface StockFeignClient {
    @GetMapping("/stock")
    String getStock();
}

        在这种方式下,当远程服务调用失败时,会调用StockFeignClientFallbackFactory类的create方法创建一个 Fallback 实例,并传入导致失败的异常对象,从而可以根据异常原因执行不同的备用逻辑。  

Fallback 优先级

配置文件 > 自定义

        在项目中,Fallback 的配置可能存在多种方式,包括通过配置属性和@Configuration类定义 Fallback,此时就涉及到 Fallback 的优先级问题。

        默认情况下,配置属性的优先级高于@Configuration类定义的 Fallback。也就是说,如果在配置文件中设置了 Fallback,同时又在@Configuration类中定义了 Fallback,那么配置文件中的 Fallback 将生效。

        如果想要改变优先级,使@Configuration类优先,可以在配置文件中设置:

spring.cloud.openfeign.client.default-to-properties: false        

通过上述配置,@Configuration类中定义的 Fallback 将具有更高的优先级 

🎉-总结 

机制重试(Retry)Fallback(降级)
核心目标

提高请求成功率(自动重试失败请求)

保障系统可用性(失败时提供备用逻辑)

触发条件

网络超时、IO异常、5xx错误等可重试异常

熔断触发、所有异常(包括重试耗尽后的失败)

执行阶段

调用过程中(尚未返回给客户端)

调用失败后(已确认无法成功)

默认行为

默认重试3次(可配置)

需显式定义Fallback类或工厂

适用场景

临时性故障(如网络抖动、服务短暂不可用)

依赖服务长期不可用、必须返回兜底结果

资源影响

可能增加服务端负载(多次重试)

无额外请求压力(直接本地逻辑)

配置关键

Retryer、超时时间、退避策略

@FeignClient(fallback=...)、熔断器集成

典型实现

new Retryer.Default(500, 5000, 3)

FallbackFactory + 异常分类处理

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值