3.OpenFeign的使用

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-democloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosregister-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 {@Autowiredprivate 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 {@Beanpublic 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;}@Overridepublic 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();}}@Overridepublic 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.mzph.cn/news/162724.shtml

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

相关文章

技术分享| anyRTC之RTN网络

RTN(Real-time Network)中文名&#xff1a;实时音视频传输网络。 RTN是最近几年由各大RTC的云厂商提出的一个全新架构的音视频实时传输网络概念。类似于直播的CDN网络&#xff0c;RTN是对音视频的实时性又强烈要求的场景而设计的&#xff0c;原理上全球端到端的时延通过RTN网络…

JSP EL表达式获取list/Map集合与java Bean对象

上文 JSP EL表达式基本使用 中 我们对EL表达式做了一个基本的了解 也做了基础的字符串数据使用 那么 我们可以来看一下我们的集合 首先 list 这个比较简单 我们直接这样写代码 <% page import"java.util.ArrayList" %> <% page import"java.util.Lis…

基于C#实现优先队列

一、堆结构 1.1性质 堆是一种很松散的序结构树&#xff0c;只保存了父节点和孩子节点的大小关系&#xff0c;并不规定左右孩子的大小&#xff0c;不像排序树那样严格&#xff0c;又因为堆是一种完全二叉树&#xff0c;设节点为 i,则 i/2 是 i 的父节点&#xff0c;2i 是 i 的…

信息系统的安全保护等级的五个级别

信息系统的安全保护等级分为五级&#xff1a;第一级为自主保护级、第二级为指导保护级、第三级为监督保护级、第四级为强制保护级、第五级为专控保护级。 法律依据&#xff1a;《信息安全等级保护管理办法》第四条 信息系统的安全保护等级分为以下五级&#xff1a;   &#…

【C语言】计算实时太阳角度(高度角、方位角),以及使用stm32单片机实时获取时间戳

整体计算方法 在编写该代码的过程中寻找了多篇博文和论文&#xff0c;综合所有文章且按网上的以0时的方位角的0&#xff0c;且随时间累加累加至360度。我修改了博文和论文的一些角度的计算方法。得到一下代码与网站计算的方位角相互验证过&#xff0c;误差不超过1 验证网站 太…

LoRaWAN 中国地区文件详细解读

目录 一、LoRaWAN简介 二、CN470-510地区参数分析 1.信道频率 2.支持功率 3.支持空速 4.最大负载大小 5.接受窗口参数 三、CN470_510默认参数 Lora LoraWAN教程 一、LoRaWAN简介 LoraWAN是一种基于LoRa远距离通信技术配套设计的一套通讯协议和系统架构。LoRaWAN网络通…

Java实现拼图游戏

1、了解拼图游戏基本功能&#xff1a; 拼图游戏内容由若干小图像块组成的&#xff0c;通过鼠标点击图像块上下左右移动&#xff0c;完成图像的拼凑。 2、拼图游戏交互界面设计与开发&#xff1a; 通过创建窗体类、菜单、中间面板和左右面板完成设计拼图的交互界面 &#xff…

外贸自建站服务器怎么选?网站搭建的工具?

外贸自建站服务器用哪个好&#xff1f;如何选海洋建站的服务器&#xff1f; 外贸自建站是企业拓展海外市场的重要手段之一。而在这个过程中&#xff0c;选择一个适合的服务器对于网站的稳定运行和优化至关重要。海洋建站将为您介绍如何选择适合的外贸自建站服务器。 外贸自建…

【STM32外设系列】GPS定位模块(ATGM336H)

&#x1f380; 文章作者&#xff1a;二土电子 &#x1f338; 关注公众号获取更多资料&#xff01; &#x1f438; 期待大家一起学习交流&#xff01; 文章目录 一、GPS模块简介二、使用方法2.1 引脚介绍2.2 数据帧介绍2.3 关于不同的启动方式 三、前置知识3.1 strstr函数3.2…

基于H1ve一分钟搭好CTF靶场

写在前面 ◉ ‿ ◉ 上一篇文章给大家详细介绍了基于H1ve搭建CTF靶场&#xff0c;以及过程中可能遇到的报错及解决方法&#xff0c;那么这篇文章&#xff0c;我总结了一下&#xff0c;将不会遇到报错的方法给到大家&#xff0c;但是前提是你的服务器最好是一个全新的哦~~~ 我…

C++基础从0到1入门编程(四)类和对象

系统学习C 方便自己日后复习&#xff0c;错误的地方希望积极指正 往期文章&#xff1a; C基础从0到1入门编程&#xff08;一&#xff09; C基础从0到1入门编程&#xff08;二&#xff09; C基础从0到1入门编程&#xff08;三&#xff09; 参考视频&#xff1a; 1.黑马程序员匠心…

香蕉派BPI-M4 Zero单板计算机采用全志H618,板载2GRAM内存

Banana Pi BPI-M4 Zero 香蕉派 BPI-M4 Zero是BPI-M2 Zero的最新升级版本。它在性能上有很大的提高。主控芯片升级为全志科技H618 四核A53, CPU主频提升25%。内存升级为2G LPDDR4&#xff0c;板载8G eMMC存储。它支持5G WiFi 和蓝牙, USB接口也升级为type-C。 它具有与树莓派 …

23. 深度学习 - 多维向量自动求导

Hi, 你好。我是茶桁。 前面几节课中&#xff0c;我们从最初的理解神经网络&#xff0c;到讲解函数&#xff0c;多层神经网络&#xff0c;拓朴排序以及自动求导。 可以说&#xff0c;最难的部分已经过去了&#xff0c;这节课到了我们来收尾的阶段&#xff0c;没错&#xff0c;生…

算法通关村第十二关-白银挑战字符串经典题目

大家好我是苏麟 , 今天带来字符串相关的题目 . 大纲 反转问题字符串反转K个一组反转仅仅反转字母反转字符串中的单词 反转问题 字符串反转 描述 : 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s的形式给出。 题目 : LeetCode 344. 反转…

webshell之扩展免杀

由于很多企业为了防止源码泄露&#xff0c;都会使用加密扩展将代码进行加密&#xff0c;那么我们就可以就将计就计&#xff0c;将webshell也利用扩展加密&#xff0c;将特征消除&#xff0c;从而达到免杀的效果 1.php-beast 扩展地址 下载dll&#xff0c;并添加至ext中 在php…

MySQL中自增id用完怎么办?

MySQL中自增id用完怎么办&#xff1f; MySQL里有很多自增的id&#xff0c;每个自增id都是定义了初始值&#xff0c;然后不停地往上加步长。虽然自然数是没有上限的&#xff0c;但是在计算机里&#xff0c;只要定义了表示这个数的字节长度&#xff0c;那它就有上限。比如&#…

python数据结构与算法-15_堆与堆排序

堆(heap) 前面我们讲了两种使用分治和递归解决排序问题的归并排序和快速排序&#xff0c;中间又穿插了一把树和二叉树&#xff0c; 本章我们开始介绍另一种有用的数据结构堆(heap)&#xff0c; 以及借助堆来实现的堆排序&#xff0c;相比前两种排序算法要稍难实现一些。 最后我…

Linux开发工具(含gdb调试教程)

文章目录 Linux开发工具&#xff08;含gdb调试教程&#xff09;1、Linux 软件包管理器 yum2、Linux开发工具2.1、Linux编辑器 -- vim的使用2.1.1、vim的基本概念2.1.2、vim的基本操作2.1.3、vim正常模式命令集2.1.4、vim末行模式命令集 2.2、vim简单配置 3、Linux编译器 -- gcc…

redis之cluster集群

1、redis-cluster集群&#xff1a;redis3.0引入的分布式存储方案 2、集群&#xff1a;由多个node节点组成&#xff0c;redis数据分布在这些节点之中 &#xff08;1&#xff09;在集群之中也分主节点和从节点 &#xff08;2&#xff09;自带哨兵模式 3、redis-cluster集群的…

腾讯云 小程序 SDK对象存储 COS使用记录,原生小程序写法。

最近做了一个项目&#xff0c;需求是上传文档&#xff0c;文档类型多种&#xff0c;图片&#xff0c;视频&#xff0c;文件&#xff0c;doc,xls,zip,txt 等等,而且文档类型可能是大文件&#xff0c;可能得上百兆&#xff0c;甚至超过1G。 腾讯云文档地址&#xff1a;https://c…