3.OpenFeign的使用

news2024/12/26 12:46:33

OpenFeign

文章目录

  • OpenFeign
    • 一. 什么是OpenFeign
    • 二. OpenFeign基础使用
      • 1.添加依赖
      • 2.配置Nacos配置信息
      • 3.在项目中开启OpenFeign
      • 4.编写OpenFeign调用代码
      • 5.调用OpenFeign接口
    • 三. OpenFeign内置的超时重试机制
      • 1.配置超时重试
      • 2.覆盖Retryer对象
    • 四.自定义超时重试机制
      • 1.自定义超时重试类
      • 2.设置配置文件
    • 五.OpenFeign超时重试底层实现
      • 1.超时重试底层实现

一. 什么是OpenFeign

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

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

OpenFeign功能升级

OpenFeign在Feign的基础上提供了以下增强和扩展功能:

  1. 更好的集成Spring Cloud组件:OpenFeign与Spring Cloud其他组件紧密集成,可以无缝地与其他Spring Cloud组件一起使用。
  2. 支持@FeignClient注解:OpenFeign引入了@FeignClient注解作为Feign客户端的标识,可以方便地定义和使用远程服务的声明式接口。
  3. 错误处理改进:OpenFeign对异常的处理做了增强,提供了更好的错误信息和异常处理机制,使得开发者可以更方便地进行错误处理。
  4. 更丰富的配置项:OpenFeign提供了丰富的配置选项,可以对Feign客户端的行为进行灵活的配置,例如超时设置、重试策略等。

二. OpenFeign基础使用

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

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

1.添加依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.配置Nacos配置信息

spring:
  application:
    name: nacos-consumer-demo
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
        register-enabled: false # 消费者(不需要注册到nacos中)

3.在项目中开启OpenFeign

在启动类文件中添加@EnableFeignClients注解即可

4.编写OpenFeign调用代码

@Service
@FeignClient("nacos-discovery") // 表示调用 nacos 中的 nacos-discovery 服务
public interface UserService {
    @RequestMapping("/user/getnamebyid") // 调用生产者的"/user/getnamebyid"接口
    public String getNameById(@RequestParam("id") int id);

}

5.调用OpenFeign接口

@RestController
public class BusinessController {

    @Autowired
    private UserService userService;

    @RequestMapping("/getnamebyid")
    public String getNameById(Integer id){
        System.out.println("------- do provider getNameById method" +
                LocalDateTime.now());
        return userService.getNameById(id);
    }

}

三. OpenFeign内置的超时重试机制

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

什么是超时重试?

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

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

OpenFeign默认是不自动开启超时重试

开启有以下步骤:

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

1.配置超时重试

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

2.覆盖Retryer对象

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

最大重试次数为3次,最大重试间隔时间是1秒,重试间隔时间是1秒

这时我们启动一个实例,并设置保护阈值为0,启动消费者。

访问服务

image-20231122192057049

此时服务无法访问,并触发了超时重试机制,这时打开生产者者的控制台:

image-20231122192120760

在控制台我们可以看到总共打印了3次日志,因为我们设置的最大重试次数是3

为什么不是4次呢?

为什么不是4次?

因为Retryer的Default方法的源码中重试次数变量attempt是从1开始的,然后核心方法continueOrPropagate中的if判断是当this.attempt++ >= this.maxAttempts 时,才抛出异常。

image-20231122192856630

image-20231122192739555

四.自定义超时重试机制

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

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

1.自定义超时重试类

常见的超时重试策略有以下三种:

  1. 固定间隔重试:每次重试之间的时间间隔固定不变。
  2. 指数间隔重试:每次重试之间的时间间隔按指数递增。
  3. 随机间隔重试:每次重试之间的时间间隔是随机的。
public class CustomRetryer implements Retryer {

    private final int maxAttempts; //最大尝试次数
    private final long backoff;   //重试间隔时间
    int attempt;  //当前重试次数

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

    public CustomRetryer(int maxAttempts, long backoff) {
        this.maxAttempts = maxAttempts;
        this.backoff = backoff;
        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) {
            ex.printStackTrace();
        }
    }

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

2.设置配置文件

spring:
  cloud:
    openfeign:
      client:
        config:
          default:
            connect-timeout: 1000 #连接超时时间
            read-timeout: 1000 #读取超时时间
            retryer: com.example.consumer.config.CustomRetryer #自定义失败重试类

启动生产者和消费者服务,并尝试调用服务,并查看控制台

image-20231122221125671

  1. 这里我们设定的重试次数是3,但为什么会打印4次呢?

    是因为在自定义重试类中的attempt变量是从0开始的。

  2. 观察日志文档的时间间隔:从2s->3s->4s,最初attempt为1,1*1+read-timeout的1s所以是2s,然后1*1+read-timeout,以此类推……

五.OpenFeign超时重试底层实现

首先我们先了解以下OpenFeign的底层实现逻辑

在这里插入图片描述

  1. 加注解:在启动类或配置类上添加 @EnableFeignClients注解
  2. 动态代理:这个注解会触发Spring框架的自动配置机制,扫描所有标记的@FeignClient的接口,并为它们创建代理实例。
  3. RequestTemplate发送HTTP请求:OpenFeign不能直接发送HTTP请求,它在动态代理里面将注解的路由地址拿出来,然后就能拼出来一个URL请求地址,然后再使用RequestTemplate去发送HTTP请求。
  4. RestTemplate依靠HTTP框架实现web请求:RestTemplate只是一个模板方法类,它只是规定了一个调用的API,底层并没有实现,依靠的是HTTP框架实现的web请求(Apache 的HttpClient框架)

1.超时重试底层实现

OpenFeign超时的底层实现是通过配置底层的HTTP客户端来实现的。OpenFeign允许在请求连接和读取数据阶段设置超时时间,具体超时配置可以通过HTTP客户端的连接超时(connectTimeout)和读取超时(readTimeout)来实现,可以在配置文件中设置超时参数。

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终止while循环)
    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);
            }
        }
    }
}

因此OpenFeign的重试功能是通过其内置的Retryer组件和底层的HTTP客户端实现的。

Retryer组件提供了重试策略的逻辑实现,而远程接口则通过HTTP客户端来完成调用。

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

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

相关文章

vue3-生命周期

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3-生命周期 目录 vue3生命周期 vue3生命周期钩子 1.1 onMounted() 1.2 onUpdated() 1.3 onU…

Airtest结合Poco对控件实施精准截图,学起来!

1.前言 最近在Q群内发现有个小伙伴提出了一个很有趣的脚本需求&#xff0c;想要实现“通过选择器获取到了控件&#xff0c;然后截图这个控件范围”&#xff0c;根据我们的Airtest的局部截图接口以及poco控件的属性查询接口是可以很快实现的~ 2.接口查找 首先我们需要知道我们…

什么软件可以做报表?

报表在现代企业和组织中扮演着重要角色。它们是数据汇总、分析和展示的重要工具&#xff0c;为管理层和决策者提供洞察和指导。但是&#xff0c;报表的制作并非易事。使用Excel或手写代码开发报表可能会带来一系列痛点&#xff0c;而现代化的解决方案——比如VeryReport报表软件…

分布式锁之传统锁回顾(一)

1. 传统锁回顾 1.1. 从减库存聊起 多线程并发安全问题最典型的代表就是超卖现象 库存在并发量较大情况下很容易发生超卖现象&#xff0c;一旦发生超卖现象&#xff0c;就会出现多成交了订单而发不了货的情况。 场景&#xff1a; 商品S库存余量为5时&#xff0c;用户A和B同…

智能导视电子指路牌是什么?

SVIP-3800系列智能电子指路牌也称智慧指路灯杆&#xff0c;智能指路牌&#xff0c;导航立柱&#xff0c;多功能指示牌&#xff0c;多功能路标&#xff0c;智能指路机器人&#xff0c;智能导视指路牌&#xff0c;问路导航机器人&#xff0c;智能路牌&#xff0c;叁仟智慧路牌、智…

电商数据采集|电商API接口接入|从京东平台获取商品SKU 主图 价格 详情数据

在进行API开发过程中&#xff0c;数据异常常常令人头痛。我们的API开车软件经过精心设计和测试&#xff0c;能够准确识别并及时处理各类数据异常。拥有稳定的运行环境&#xff0c;保障了您的开发进程不受干扰&#xff0c;让您的工作更加顺畅高效。 京东获得JD商品详情 API 返…

AI助力钢铁产业数字化,python基于YOLOv5开发构建钢铁产业产品智能自动化检测识别系统

AI为工业产业智能化数字化赋能早已不是什么新鲜事&#xff0c;越来越多的行业和领域开始更大范围去拥抱AI&#xff0c;享受科技带来的变革力量&#xff0c;在我们之前的文章中也有很多相关领域项目的实践经历&#xff0c;本文的核心目标就是想要基于钢铁领域产品数据来开发构建…

VirtualBox下win主机如何访问linux虚拟机文件夹

目录 ​编辑 方法1&#xff1a;通过VirtualBox自带的共享文件夹&#xff08;Win->linux&#xff09; 方法2&#xff1a;通过Samba方法本地网络访问(Linux->win) 我使用的VirtualBox版本为7.0.4,主机是Window系统&#xff0c;虚拟机是Linux系统 方法1&#xff1a;通过Vir…

易点易动设备管理系统提升设备能耗管理和设备状态监控效率

如今&#xff0c;能源效率和设备状态监控对于企业来说变得越发重要。传统的设备管理方式往往存在能耗浪费和难以实时监控设备状态的问题。为了解决这些问题&#xff0c;易点易动设备管理系统应运而生。本文将介绍易点易动设备管理系统的功能和优势&#xff0c;以及如何通过它提…

深度学习之六(自编码器--Autoencoder)

概念 自编码器(Autoencoder)是一种神经网络架构,用于无监督学习和数据的降维表示。它由两部分组成:编码器(Encoder)和解码器(Decoder)。 结构: 编码器(Encoder): 接收输入数据并将其压缩为潜在表示(latent representation),通常比输入数据的维度要低。编码器的…

Sam Altman回归OpenAI,新董事会成员曝光!

11月22日下午&#xff0c;OpenAI在社交平台宣布&#xff0c;在原则上已达成协议&#xff0c;让 Sam Altman重返 OpenAI担任首席执行官&#xff0c;并重组董事会。稍后会公布更详细的内容。 初始董事会成员包括前Salesforce联合首席执行官Bret Taylor&#xff08;担任主席&…

【AI读论文】AutoML的8年回顾:分类、综述与趋势

论文标题&#xff1a;Eight years of AutoML: categorisation, review and trends 论文链接&#xff1a;https://link.springer.com/article/10.1007/s10115-023-01935-1 本文主要围绕自动机器学习&#xff08;AutoML&#xff09;展开了系统性的文献综述&#xff0c;总结了该领…

德迅云安全-德迅卫士:保障您的主机安全

主机安全是指保证主机在数据存储和处理的保密性、完整性、可用性&#xff0c;包括硬件、固件、系统软件的自身安全&#xff0c;以及一系列附加的安全技术和安全管理措施。 为什么要主机安全&#xff1f; 服务器一旦被黑客入侵&#xff0c;个人和企业面临以下安全风险&#xff…

基于springboot实现家政服务管理平台项目【项目源码+论文说明】

摘要 随着家政服务行业的不断发展&#xff0c;家政服务在现实生活中的使用和普及&#xff0c;家政服务行业成为近年内出现的一个新行业&#xff0c;并且能够成为大众广为认可和接受的行为和选择。设计家政服务管理平台的目的就是借助计算机让复杂的销售操作变简单&#xff0c;…

unity Toggle,初始时默认不选中,若选中则不可取消选中。不写码实现其效果

实现效果&#xff1a; 初始默认时&#xff1a; 选中时&#xff1a; 零代码实现&#xff1a; 步骤1 步骤2 步骤3

Pycharm设置文件头部声明注释

设置头部声明 英文版&#xff1a;点击file-->settings-->editor-->file and code templates-->选择Python Script 中文版如下&#xff1a; 复制如下内容 #!/usr/bin/env python # -*- coding: utf-8 -*- # Time : 2023/11/23 10:05 # Author : wyq # File …

Python + Docker 还是 Rust + WebAssembly?

在不断发展的技术世界中&#xff0c;由大语言模型驱动的应用程序&#xff0c;通常被称为“LLM 应用”&#xff0c;已成为各种行业技术创新背后的驱动力。随着这些应用程序的普及&#xff0c;用户需求的大量涌入对底层基础设施的性能、安全性和可靠性提出了新的挑战。 Python 和…

微信开放平台Android平台应用签名怎么填写

winR 输入cmd 进到本地签名文件的目录下 输入 keytool -list -v -keystore <keystore文件路径> -alias <别名>请将 <keystore文件路径> 替换为您的密钥库文件&#xff08;通常是 .jks 或 .keystore 文件&#xff09;的路径&#xff0c;而 <别名> 则是…

如何判断交流回馈老化测试负载是否合格?

交流回馈老化测试负载是用于模拟实际工作环境中设备运行状态的测试工具&#xff0c;主要用于检测设备的耐久性和稳定性。 负载性能&#xff1a;需要检查负载的性能是否符合设计要求&#xff0c;这包括负载的功率、电流、电压等参数是否在规定的范围内&#xff0c;以及负载的工作…

豪华程度堪比飞机头等舱?奔驰在北美发布Tourrider系列巴士

今年三月&#xff0c;奔驰工厂附近出现了一台特殊的测试车。其突出的前保险杠以及竖置双风挡等特殊配置&#xff0c;都在暗示着它并非是为欧洲市场打造。 根据特征推测&#xff0c;这台车应该是为北美市场打造。 就在昨天&#xff0c;奔驰发布了旗下全新Tourrider系列豪华客车&…