OpenFeign 入门与实战

news2024/10/6 2:32:48

一、什么是 OpenFeign 

OpenFeign 的全称为 Spring Cloud OpenFeign,是Spring Cloud 团队开发的一款基于Feign 的框架,声明式 Web 服务客户端

Feign 是 Netflix 开源的一个声明式的 Web 服务客户端,它简化了基于HTTP 的服务调用,使得服务间通讯变得更加简单灵活。Feign 通过定义接口、注解和动态代理等方式,将服务调用的过程封装起来,开发者只需要定义服务接口,而无需关心底层的 HTTP 请求和序列化等细节。

OpenFeign vs Feign 的功能升级

  1.  更好的集成 Spring Cloud 组件:OpenFeign 与 Spring Cloud 其他组件(如服务发现,负载均衡等)紧密集成,可以无缝地与其他Spring Cloud 组件一起使用。
  2. 支持 @FeignClient 注解:OpenFeign 引入了 @FeignClient 注解作为 Feign 客户端的标识,可以方便地定义和使用远程服务地声明式接口。
  3. 错误处理改进:OpenFeign 对异常的处理做了增强,提供了更好的错误信息和错误异常处理机制,使得开发者可以更方便地进行错误处理。例如:OpenFeign 提供返回错误响应或请求失败时,OpenFeign 会调用回退策略中的逻辑,提供一个默认的处理结果。
  4. 更丰富的配置项:OpenFeign 提供了丰富的配置选项,可以对 Feign 客户端的行为进行灵活的配置,例如超时设置、重试策略等。

二、OpenFeign 基础使用

OpenFeign 通常要配合注册中心一起使用,并且新版本 OpenFeign 也必须和负载均衡器一起使用,所以它的基础使用步骤如下:

  1. 添加依赖(Nacos 注册中心、OpenFeign、Spring Cloud LoadBalancer)
  2. 配置 Nacos 服务端信息
  3. 在项目中开启 OpenFeign
  4. 编写 OpenFeign 调用代码
  5. 编写代码通过 OpenFeign 调用生产者

具体参考 Nacos-注册中心-CSDN博客

三、超时重传机制

在微服务框架中,服务之间是通过网络进行通信的,而网络是非常复杂和不稳定的,所以在调用服务时可能会失败或超时,那么在这种情况下,我们就需要个 OpenFeign 配置超时重试机制了。

什么时超时重试?

超时重试就是一种在网络通信中常用的策略,用于处理请求在一定时间内未能得到响应或得到超时响应的情况。当发起请求后,如果在规定的时间内没有得到预期的响应,就会触发超时重试机制,重新发送请求。

超时重试的目的主要是提高请求的可靠性和稳定性,以应对网络不稳定、服务不可用、响应延迟等不确定因素。

3.1 配置超时重试 

spring:
  cloud:    
    openfeign:
      client:
        config:
          default:            #全局配置
            connect-timeout: 1000 #连接超时时间
            read-timeout: 1000    #读取超时时间

 3.2 覆盖 Retryer

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

四、自定义超时重传机制

自定义重试类

public class MyRetryer implements Retryer {
    private final int maxAttempts;
    private final long period;
    int attempt;

    public MyRetryer(){
        this.maxAttempts=3;
        this.period=1;
        this.attempt=0;
    }

    public MyRetryer(int maxAttempts,long period){
        this.maxAttempts=maxAttempts;
        this.period=period;
        this.attempt=0;
    }



    @Override
    public void continueOrPropagate(RetryableException e) {
        if(attempt++>=maxAttempts){
            throw e;
        }
        long interval=period;
        try {
            //重试间隔时间
            Thread.sleep((interval*(attempt)));
        } catch (InterruptedException ex) {
            throw new RuntimeException(ex);
        }
    }

    @Override
    public Retryer clone() {
        return new MyRetryer(maxAttempts,period);
    }
}

设置配置文件

spring:
  application:
    name: nacos-consumer-demo
  cloud:
    nacos:
      discovery:
        username: nacos
        password: nacos
        server-addr: localhost:8848
        register-enabled: true
    openfeign:
      client:
        config:
          default:            #全局配置
            connect-timeout: 1000 #连接超时时间
            read-timeout: 1000    #读取超时时间
            retryer: com.example.consumer.config.MyRetryer #自定义重试类

server:
  port: 58080

五、超时重试底层实现

5.1 超时重试底层原理

OpenFeign 超时的底层实现是通过配置底层的HTTP 客户端来实现的。OpenFeign 允许你在请求连接和读取数据阶段设置超时时间,具体的超时时间可以通过设置HTTP 客户端的连接超时和读取超时来实现,可以在配置文件中设置超时参数。OpenFeign 底层的HTTP 客户端,可以使用 Apache HttpClient 或 OkHttpClient 来实现,默认使用的是 ApacheClient 实现的。

5.2 重试代码底层实现

通过观察 OpenFeign 的源码实现可以了解重试功能的底层实现,它的源码在 SynchronousMethodHandler 的 invoke 方法下,如下所示

public Object invoke(Object[] argv) throws Throwable {
     RequestTemplate template = this.buildTemplateFromArgs.create(argv);
     Request.Options options = this.findOptions(argv);
     Retryer retryer = this.retryer.clone();
     // 死循环,如果成功或者重试结束就返回【通过 throw 终止 weile 循环】
     while(true) {
        try {   
             //通过 HTTP Client 发起通信
             return this.executeAndDecode(template, options);
        } catch (RetryableException var9) {
             RetryableException e = var9;
             try {
                // 判断是否重试
                    retryer.continueOrPropagate(e);
                } catch (RetryableException var8) {
                    Throwable cause = var8.getCause();
                    if (this.propagationPolicy == ExceptionPropagationPolicy.UNWRAP && cause != null) {
                        throw cause;
                    }
                    throw var8;
                }
                if (this.logLevel != Level.NONE) {
                    this.logger.logRetry(this.metadata.configKey(), this.logLevel);
                }
            }
        }
    }

retryer 中 continueOrPropagate 的实现源码如下:

public interface Retryer extends Cloneable {
    Retryer NEVER_RETRY = new Retryer() {
        public void continueOrPropagate(RetryableException e) {
            throw e;
        }

        public Retryer clone() {
            return this;
        }
    };

    void continueOrPropagate(RetryableException var1);

    Retryer clone();

    public static class Default implements Retryer {
        private final int maxAttempts;
        private final long period;
        private final long maxPeriod;
        int attempt;
        long sleptForMillis;

        public Default() {
            this(100L, TimeUnit.SECONDS.toMillis(1L), 5);
        }

        public Default(long period, long maxPeriod, int maxAttempts) {
            this.period = period;
            this.maxPeriod = maxPeriod;
            this.maxAttempts = maxAttempts;
            this.attempt = 1;
        }

        protected long currentTimeMillis() {
            return System.currentTimeMillis();
        }

        public void continueOrPropagate(RetryableException e) {
            if (this.attempt++ >= this.maxAttempts) {
                throw e;
            } else {
                long interval;
                if (e.retryAfter() != null) {
                    interval = e.retryAfter().getTime() - this.currentTimeMillis();
                    if (interval > this.maxPeriod) {
                        interval = this.maxPeriod;
                    }

                    if (interval < 0L) {
                        return;
                    }
                } else {
                    interval = this.nextMaxInterval();
                }

                try {
                    Thread.sleep(interval);
                } catch (InterruptedException var5) {
                    Thread.currentThread().interrupt();
                    throw e;
                }

                this.sleptForMillis += interval;
            }
        }

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

        public Retryer clone() {
            return new Default(this.period, this.maxPeriod, this.maxAttempts);
        }
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1903871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一位3D打印工程师繁忙的一天

早晨&#xff1a;准备与规划 7:00 AM - 起床与晨练 3D打印工程师早起进行晨练&#xff0c;如跑步或瑜伽&#xff0c;以保持身心健康。晨练后&#xff0c;享用一顿健康的早餐&#xff0c;为一天的繁忙工作做好准备。 8:00 AM - 检查邮件和项目进展 在开始工作前&#xff0c;先…

封装了一个仿照抖音效果的iOS评论弹窗

需求背景 开发一个类似抖音评论弹窗交互效果的弹窗&#xff0c;支持滑动消失&#xff0c; 滑动查看评论 效果如下图 思路 创建一个视图&#xff0c;该视图上面放置一个tableView, 该视图上添加一个滑动手势&#xff0c;同时设置代理&#xff0c;实现代理方法 (BOOL)gestur…

Zkeys三方登录模块支持QQ、支付宝登录

1&#xff0c;覆盖到根目录&#xff0c;并导入update.sql数据库文件到Zkeys数据库里 2. 后台系统权限管理&#xff0c;配置管理员权限-系统类别-找到云外科技&#xff0c;全部打勾 3&#xff0c;后台系统设置找到云外快捷登录模块填写相应的插件授权配置和登录权限配置&#x…

【python中级】图像从从笛卡尔坐标系转换为极坐标系

【python中级】图像从从笛卡尔坐标系转换为极坐标系 1.背景2.生成二维图3.极坐标转换1.背景 笛卡尔坐标系就是我们常说的直角坐标系。 笛卡尔坐标系,也称为直角坐标系,是由法国数学家和哲学家勒内笛卡尔(Ren Descartes)发明的一种二维或三维坐标系统。它使用两个或三个相互…

人工智能在病理切片虚拟染色及染色标准化领域的系统进展分析|文献速递·24-07-07

小罗碎碎念 本期文献主题&#xff1a;人工智能在病理切片虚拟染色及染色标准化领域的系统进展分析 这一期文献的速递&#xff0c;是有史以来数量最大的一次&#xff0c;足足有十一篇&#xff0c;本来打算分两期写&#xff0c;但是为了知识的系统性&#xff0c;我决定咬咬牙&…

texStudio使用(小白)

原先使用overleaf在线编译&#xff0c;可能eps格式的图片太大导致需要充钱&#xff0c;所以考虑本地安装 安装教程参考B站视频&#xff1a;B站Latex本地编译器安装&#xff1a;TexLive TextStudio 踩到坑&#xff1a; 1. 编译器位置要选择对 因为BibTex选成了Biber导致出现无…

minist数据集分类模型的训练

minist数据集训练 训练方法&#xff1a;利用pytorch来实现minist数据集的分类模型训练 训练模型如下图所示 模型代码&#xff1a; import torch from torch import nn from torch.nn import Flattenclass Net(nn.Module):def __init__(self):super().__init__()self.module …

文件管理下:文件函数的学习

前言 Hello,小伙伴们你们的作者君又来了&#xff0c;上次我们简单介绍了文件的坐拥并简单提到了数据的读取&#xff0c;和C语言的默认流的作用&#xff0c;今天我将继续带领大家探索文件的奥秘&#xff0c;大家准别好了吗&#xff1f; 在内容开始之前还是按照惯例&#xff0c…

**kwargs 字典解包传参的方式

字典解包传参 在Python中&#xff0c;****kwargs**是一种通过字典解包 (dictionary unpacking) 的方式进行参数传递的方式。它将一个字典的键值对解包并传递给函数的命名参数。 示例代码 kwargs实参: {name: "jordan", age: 18, score: [80, 85, 85]} get_info形…

下载linux的吐槽

本来这几天放假了&#xff0c;想下一个linux玩一玩 教程&#xff08;我就是根据这个教程进行下载的&#xff0c;但是呢在进行修改BIOS 模式的 地方遇见了困难&#xff0c;也许是电脑修过的原因&#xff0c;我狂按F12 以及 FnF12都没有BIOS设置&#xff0c;只有一个让我选择用w…

前端扫盲:cookie、localStorage和sessionStorage

cookie、localStorage和sessionStorage都是存储数据的方式&#xff0c;他们之间有什么不同&#xff0c;各有什么应用场景&#xff0c;本文为您一一解答。 一、什么是cookie、localStorage和sessionStorage 1. Cookie是一种存储在用户计算机上的小型文本文件&#xff0c;由服务…

子数组按位与为k

注意这里的子数组是连续的非空的数组&#xff0c;我们要学会与处理就是求交集 class Solution { public:long long countSubarrays(vector<int>& nums, int k) {long long ans 0;for (int i 0; i < nums.size(); i) {int x nums[i];for (int j i - 1; j > …

通过消息传递同步操作

通信顺序进程&#xff08;CSP&#xff09; 是一种形式语言&#xff0c;用来描述并发性系统间进行交互的模式 每个线程或进程独立运行&#xff0c;它们之间仅通过消息传递进行通信&#xff0c;而不是直接共享状态 每个线程实际上都是一个状态机&#xff1a;当它接收到一条消息时…

Zabbix监控软件

目录 一、什么是Zabbix 二、zabbix监控原理 三、zabbix 安装步骤 一、什么是Zabbix ●zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 ●zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的…

基于LoFTR_TRT项目实现LoFTR模型的trt推理与onnx推理,3060显卡下320图像30ms一组图

本博文主要记录了使用LoFTR_TRT项目将LoFTR模型导出为onnx模型&#xff0c;然后将onnx模型转化为trt模型。并分析了LoFTR_TRT与LoFTR的基本代码差异&#xff0c;但从最后图片效果来看是与官网demo基本一致的&#xff0c;具体可以查看上一篇博客记录。最后记录了onnx模型的使用【…

深入探索 Python 中的数据维数:高维数据处理方法与应用

Python 数据维数 在数据科学和机器学习领域&#xff0c;理解数据的维度是至关重要的。Python作为一种强大而灵活的编程语言&#xff0c;提供了丰富的工具和库来处理各种维度的数据。本文将介绍Python中数据维数的概念&#xff0c;以及如何使用Python库来处理不同维度的数据。 什…

27 防火墙不同区域之间是如何通信

26 华三防火墙安全区域-CSDN博客 目标实现不同区域的通信 1 给防火墙配置IP地址 WEB页面配置IP地址 2 在PC机上配置对应对IP地址 &#xff08;该要启用的接口一定要启用 IP地址 子网掩码 网关 一定要查看好&#xff09; 3 将配置好的IP地址对应的不同接口加入到不同的区域上去 …

关于忠诚:忠于自己的良知、理想、信念

关于忠诚&#xff1a; 当我们面对公司、上司、爱人、恋人、合作伙伴还是某件事&#xff0c;会纠结离开还是留下&#xff0c;这里我们要深知忠诚的定义&#xff0c;我们不是忠诚于某个人、某件事、或者某个机构&#xff0c;而是忠诚于自己的良知&#xff0c;忠诚于自己的理想和…

【计算机毕业设计】020基于weixin小程序订餐系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

分班结果老师怎么发给家长?

分班结果老师怎么发给家长&#xff1f; 随着新学期的脚步渐近&#xff0c;老师们的工作也变得愈发繁忙。从准备教学计划到整理课程材料&#xff0c;每一项任务都不容小觑。而其中&#xff0c;分班结果的告知工作&#xff0c;更是让不少老师头疼不已。传统的分班通知方式&#…