OpenFeign入门

OpenFeign是Spring Cloud OpenFeign,是Spring Cloud团队开发的基于Feign的框架

1、OpenFeign功能升级

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

(1)便于集成Spring Cloud组件:OpenFeign与Spring Cloud其他组件(服务发现、负载均衡等)紧密集成

(2)支持@FeignClient注解:OpenFeign引入了@FeignClient注解作为Feign客户端的标识,可以方便地定义和使用远程服务的声明式接口

(3)错误处理改进:OpenFeign对异常处理增强,例如:OpenFeign提供错误编码器(DefaultErrorDecoder)和回退策略(当服务端返回错误响应或请求失败时,OpenFeign调用回退策略中的逻辑,提供一个默认的处理结果)

(4)更丰富的配置项:例如:超时设置、重试策略等

2、OpenFeign基本使用

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

(1)添加依赖(Nacos注册中心、OpenFeign、Spring Cloud LoadBalancer)

(2)配置Nacos服务信息

(3)在项目中开启OpenFeign

(4)编写OpenFeign调用代码

(5)编写代码通过OpenFeign调用生产者

代码的基本分块

2.1、添加依赖

总共添加三个依赖:Nacos注册中心、OpenFeign和LoadBalancer(在nacosr入门的时候,添加过这些依赖进行演示)

        <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.2、配置Nacos服务端信息

以下采用yml格式的配置文件

2.2.1、消费者

spring:
   application:
     name: consumer
   cloud:
     nacos:
       discovery:
         server-addr: localhost:8848
         username: nacos
         password: nacos
         register-enabled: false  #表示注册显示 消费者 不需要显示
server:
  port: 8080

2.2.2、提供者

spring:
  application:
    name: provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
server:
  port: 9091

2.2.3、提供者业务代码

提供者访问路径 /user/getname 这里的路径的一会要提供给消费者的

@RestController
@RequestMapping("/user")
public class UserController {

    //为了获取端口号 注入webServer相关注解
    @Autowired
    private WebServerApplicationContext serverApplicationContext;

    @RequestMapping("/getname")
    public String getName(@RequestParam("id") Integer id) throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("------超时重试--------"+ LocalDateTime.now());
        return "provider  : "+id+" | port "+serverApplicationContext.getWebServer().getPort();
    }
}

2.3、项目中开启OpenFeign

在消费者的Spring Boot启动类添加@EnableFeignClients注解

2.4、编写OpenFeign调用代码

消费者:接口的访问路径就是远程调用 这里路径是我们要访问提供者的路径,方法和提供者也是一样的,除了没有方法体

@Service
@FeignClient("provider")  // 我们需要远程调用的服务, 也就是生产者名称 我们刚刚写的provider
public interface UserService {
    @RequestMapping("/user/getname") //生产者的调用接口
    public String getName(@RequestParam("id") Integer id);
}

2.5、调用OpenFeign接口代码

@RestController
public class UserController {
    @Autowired   // 注入我们远程调用的接口
    private UserService userService;
    @RequestMapping("/getname")
    public String getName(Integer id){
        return "consumer 调用 "+userService.getName(id);
    }
}

3、超时重试机制

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

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

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

OpenFeign默认情况下是不会自动开启超时重试的,所以想要开启超时重试,需要下面的步骤

(1)配置超时重传

(2)覆盖Retryer对象

3.1、配置超时重试

超时配置消费者访问的时候超时需要配置的,不是提供者

spring:
   application:
     name: consumer
   cloud:
     nacos:
       discovery:
         server-addr: localhost:8848
         username: nacos
         password: nacos
         register-enabled: false  #表示注册显示 消费者 不需要显示
     openfeign:    #OpenFeign配置超时重传配置
       client:
         config:
           default:  #全局配置
             connect-timeout: 1000 #这里是ms单位 连接时间1s
             read-timeout: 1000 # 读取超时时间 1s
server:
  port: 8080

光配置是不行,这里需要从写一下Retryer

3.2、覆盖Retryer

在消费者(consumer)这个子模块中写config层,写一个Retryer注入到对象中

@Configuration
public class RetryerConfig {
    @Bean
    public Retryer retryer(){
        //第一个参数 是 时间间隔   第二个参数 是最大超时时间  第三个参数是最大重试次数
        return new Retryer.Default(
                1000,    
                3000,              
                3
        );
    }
}

4、自定义超时重试机制

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

(1)自定义超时重试类(实现Retryer接口,并重写continueOrPropagate方法)

(2)设置配置文件

4.1、自定义超时重试类

常见超时重试策略有以下三种:
(1)固定间隔重试:每次重试之间的时间间隔固定不变,例如每次重试之间相隔1秒

(2)指数重试:每次重试之间的时间间隔按指数递增。例如,初始间隔为1秒,每次重试后加倍,第一次1s,第二次2s,第三次4s依次类推

(3)随机间隔重试:每次重试之间的时间间隔是随机的,通过引入随机性来防止多个失败请求同时发生,例如,每次重试的时间间隔在一定范围内随机选择

我们这里就写一个类继承Retryer 开始我们的自定义超时重试

我们这里同样是在config层写的

//重写不需要注入 直接会进行覆盖 实现 Retryer接口需要 重写continueOrPropagate和clone
//模仿这写就行
public class CustomRetryer implements Retryer {

    private final  int maxAttempts; //最大访问次数
    private final  long backoff; //重试间隔时间
    private 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()+"| 执行一次重试");
        try {
            Thread.sleep(interval*attempt);
        } catch (InterruptedException ex) {
            throw new RuntimeException(ex);
        }
    }

    /*
    *克隆创建独立实例
    * */
    @Override
    public Retryer clone() {
        return new CustomRetryer(maxAttempts,backoff);
    }
}

4.2、设置配置文件

只重写重试策略是不行的,还需要进行配置,让重试得时候跑我们自定义重试策略

spring:
   application:
     name: consumer
   cloud:
     nacos:
       discovery:
         server-addr: localhost:8848
         username: nacos
         password: nacos
         register-enabled: false  #表示注册显示 消费者 不需要显示
     openfeign:    #OpenFeign配置超时重传配置
       client:
         config:
           default:  #全局配置
             connect-timeout: 1000 #这里是ms单位 连接时间1s
             read-timeout: 1000 # 读取超时时间 1s
             retryer: com.example.consumer.config.CustomRetryer  #添加路径
server:
  port: 8080

运行结果:

这里的重试是有三次的,会打印四个超时重试,相差时间为2,3,4s,因为我们自定超时重试时间就是按照次数来计算时间的,第一次:间隔时间+1=2s   第二次:间隔时间+2=3s

也就是 间隔时间 + 第几次 = 超时时间

 5、超时重试底层实现

“超时重试”基本就两个动作:“超时”和“重试”,对应底层实现也是不同的

5.1、超时底层实现

OpenFeign超时的底层实现是通过HTTP客户端来实现的

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

OpenFeign底层的HTTP客户端,可以使用Apache HttpClient或OkHttpClient来实现,默认使用的是Apache HttpClient来实现的

5.2、重试底层实现

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

底层实现基于RequestTemplate的

 retryer实现continueOrPropagate方法

 总结:OpenFeign的重试功能是通过其内置的Retryer组件和底层的HTTP客户端实现的,Retryer组件提供了重试策略的逻辑实现,而远程接口则通过HTTP客户端来完成调用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

float和double(浮点型数据)在内存中的储存方法

作者&#xff1a;元清加油 主页&#xff1a;主页 编译环境&#xff1a;visual studio 2022 (x86) 相信大家都知道数据在内存中是以二进制储存的 整数的储存方法是首位是符号位&#xff0c;后面便是数值位 那么浮点数在内存中是怎么储存的呢&#xff1f;我们先来看一个例子&am…

C语言-内存函数详解

文章目录 1. memcpy使用和模拟实现2. memmove使用和模拟实现3. memset函数的使用4. memcmp函数的使用 1. memcpy使用和模拟实现 返回类型和参数&#xff1a; void * memcpy ( void * destination, const void * source, size_t num );1.函数memcpy从source的位置开始向后复制…

叠加原理(superposition principle)、线性系统

叠加原理&#xff08;superposition principle&#xff09;&#xff1a;指对一个系统而言&#xff0c;两个或多个输入产生的输出&#xff0c;等于这几个输入单独引起的输出的和&#xff0c;即输入的叠加等于各输入单独引起的输出的叠加。 线性系统&#xff1a;一个系统&#x…

Java毕业设计 SpringBoot 车辆充电桩系统

Java毕业设计 SpringBoot 车辆充电桩系统 SpringBoot 车辆充电桩系统 功能介绍 首页 图片轮播 登录注册 充电桩展示 搜索充电桩 充电桩报修 充电常识 个人中心 我的收藏 后台管理 登录 首页 个人中心 维修员管理 用户管理 电桩类别管理 充电桩管理 充电桩报修管理 维修回复管…

B树与B+树的对比

B树&#xff1a; m阶B树的核心特性&#xff1a; 树中每个节点至多有m棵子树&#xff0c;即至多含有m-1个关键字根节点的子树数属于[2, m]&#xff0c;关键字数属于[1, m-1]&#xff0c;其他节点的子树数属于 [ ⌈ m 2 ⌉ , m ] [\lceil \frac{m}{2}\rceil, m] [⌈2m​⌉,m]&am…

机器学习:攻击方法FGSM系列

任务 FGSM I-FGSM MI-FGSM Ensemble Attack 攻击评价指标 准确率越低表明攻击越好 数据 预训练模型 BaseLine 实践

Java、PHP、C语言经典项目源码合集推荐(一)

&#xff08;一&#xff09;.Java智慧校园系统源码、 智慧学校源码、 智慧校园平台源码、智慧校园电子班牌系统源码、中小学智慧校园系统源码、 原生微信小程序端源码、电子班牌系统源码 项目技术栈 1、使用springboot框架Javavue2 2、数据库MySQL5.7 3、移动端小程序使用小程…

UWB实时定位系统源码,历史活动轨迹显示,视频联动,电子围栏

UWB实时定位系统源码&#xff0c;工厂企业人员安全定位&#xff0c;UWB源码 行业背景 工业企业多存在很多有毒有害、高危高压等生产环境&#xff0c;带电设备众多&#xff0c;容易发生安全事故&#xff1b;人员只能凭记忆遵守各项生产安全规范&#xff0c;如某些危险区域范围、…

运维 | 浅谈云计算的相关概念和分类

关注&#xff1a;CodingTechWork 云计算 云计算的出现 云计算是采用的按需付费的方式&#xff0c;通过互联网访问云服务器上的服务器、数据库等服务。云计算为何会出现&#xff1f;  如果现在一个企业想要进行软件管理部署&#xff0c;首先需要服务器主机和网络规划&#…

手把手教你如何在Linux下写进度条小程序(附源码)

效果展示 录屏2023 一、建立文件 mkdir ProgressBar //在当前目录下&#xff0c;建立新的目录 cd ProgressBar //进入这个目录 touch main.c makefile progressbar.c progressbar.h //在ProgressBar这个目录建立这几个文件进入ProgressBar这个目录之后&#xff0c;使…

【开源】基于Vue和SpringBoot的食品生产管理系统

项目编号&#xff1a; S 044 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S044&#xff0c;文末获取源码。} 项目编号&#xff1a;S044&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 加工厂管理模块2.2 客户管理模块2.3…

过滤器的应用

javaWeb三剑客: 1. Servlet:接收请求,处理请求(单例,也就是说&#xff0c;多个用户请求的的servlet是同一个对象) 2. Filter:拦截请求(单例->也就是说&#xff0c;多个用户请求的的filter是同一个对象) 3. Listem: 监听用户/服务器行为,javaWeb三剑客: 过滤器的实现 1&…

Arrays.asList() 与 Collections.singletonList()的恩怨情仇

1. 概述 列表是我们使用 Java 时常用的集合类型。 众所周知&#xff0c;我们可以轻松地用一行初始化一个List。例如&#xff0c;当我们想要初始化一个只有一个元素的List时&#xff0c;我们可以使用Arrays.asList()方法或Collections.singletonList()方法。 在本文中&#x…

HCIP-十、BGP基础

十、BGP基础 实验拓扑实验需求及解法1.R1 属于 AS100&#xff0c;R2/3/4 属于 AS200&#xff0c;R5 属于 AS3002.AS200 内运行 OSPF3.建立 IBGP 邻居4.建立 EBGP 邻居5.BGP 发布路由6.路由黑洞 实验拓扑 实验需求及解法 本实验模拟 ISP 网络拓扑&#xff0c;运行 BGP。如图所示…

【DevOps】基于 KubeSphere 的 Kubernetes 生产实践之旅(万字长文)

基于 KubeSphere 的 Kubernetes 生产实践 1.KubeSphere 简介1.1 全栈的 Kubernetes 容器云 PaaS 解决方案1.2 选型理由&#xff08;从运维的角度考虑&#xff09; 2.部署架构图3.节点规划3.1 软件版本3.2 规划说明3.2.1 K8s 集群规划3.2.2 存储集群3.2.3 中间件集群3.2.4 网络规…

kafka,RabbitMQ,RocketMQ,他们之间的区别,架构,如何保证消息的不丢失,保证不重复消费,保证消息的有序性

文章目录 Kafka、RabbitMQ、RocketMQ 之间的区别是什么&#xff1f;性能数据可靠性服务可用性功能 RabbitMQ如何保证消息不丢失&#xff1f;Kafka 的架构说一下&#xff1f;Kafka 怎么保证消息是有序的&#xff1f;Kafka 怎么解决重复消费&#xff1f;Kafka 怎么保证消息不丢失…

TCP/IP协议、三次握手、四次挥手

TCP/IP TCP/IP协议分层TCP头部三次握手TCP四次挥手常见问题1、什么是TCP网络分层2、TCP为什么是三次握手&#xff0c;不是两次或者四次&#xff1f;3、TCP为什么是四次挥手&#xff0c;为什么不能是三次挥手将第二次挥手和第三次挥手合并&#xff1f;4、四次挥手时为什么TIME_W…

spring boot整合Jasypt实现配置加密

文章目录 目录 文章目录 前言 一、Jasypt是什么&#xff1f; 二、使用步骤 1.引入 2.测试使用 3.结果 总结 前言 一、Jasypt是什么&#xff1f; Jasypt&#xff08;Java Simplified Encryption&#xff09;是一个Java库&#xff0c;提供了一种简单的加密解密方式&#xff0c…

web:[ZJCTF 2019]NiZhuanSiWei1

题目 点进题目&#xff0c;网页显示如下&#xff0c;需要代码审计 $_GET["text"]和$_GET["file"]来获取传入的两个参数text和file。使用isset()函数来检查$text变量是否已设置并且不为null。如果设置了并且不为null&#xff0c;则执行下面的逻辑。在下面的…

Qt4用子类化ProxyModel和子类化MainWindow实现全表筛选,中文排序和复制粘贴

目录 1 需求 2 子类化ProxyModel实现全表筛选 3 字符串列表实现中文排序 3.1 Qt5中文排序 3.2 Qt4排序 4 表格的复制粘贴 5 应用 1 需求 模型视图编程是Qt开发的基本功&#xff0c;其中有几个关键问题需要解决&#xff1a; 全表筛选&#xff0c;或者说多列搜索中文排序…