2.OpenFeign 入门与使用

2.OpenFeign 入门与使用

  • 1.什么是 OpenFeign?
  • 2.OpenFeign 基础使用
    • 2.1 添加依赖
    • 2.2 配置 Nacos 服务端信息
    • 2.3 项目中开启 OpenFeign
    • 2.4 编写 OpenFeign 调用代码
    • 2.5 调用 OpenFeign 接口代码
  • 3.超时重试机制
    • 3.1 配置超时重试
    • 3.2 覆盖 Retryer
  • 4.自定义超时重试机制
    • 4.1 自定义超时重试类
    • 4.2 设置配置文件
  • 5.超时重试底层实现
    • 5.1 超时底层实现
    • 5.2 重试底层实现

1.什么是 OpenFeign?

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

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

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

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

2.OpenFeign 基础使用

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

spring:application:name: nacos-consumer-democloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosregister-enabled: false # 消费者(不需要将此服务注册到nacos)openfeign:client:config:default:connect-timeout: 1000 # 连接超时时间read-timeout: 1000 # 读取超时时间retryer: com.example.consumer.config.CustomRetryer
server:port: 8080

2.3 项目中开启 OpenFeign

@SpringBootApplication
@EnableFeignClients // 开启 OpenFeign
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}}

2.4 编写 OpenFeign 调用代码

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

2.5 调用 OpenFeign 接口代码

@RestController
public class BusinessController {@Autowiredprivate UserService userService;@RequestMapping("/getnamebyid")public String getNameById(Integer id){return userService.getNameById(id);}}

3.超时重试机制

在微服务架构中,服务之间是通过网络进行通信的,而网络是非常复杂性和不稳定的,所以在调用服务时可能会失败或超时,那么在这种情况下,我们就需要给 OpenFeign 配置超时重试机制了。
什么是超时重试?
答:超时重试是一种在网络通信中常用的策略,用于处理请求在一定时间内未能得到响应或得到超时响应的情况。当发起请求后,如果在规定的时间内没有得到预期的响应,就会触发超时重试机制,重新发送请求。超时重试的主要目的是提高请求的可靠性和稳定性,以应对网络不稳定、服务不可用、响应延迟等不确定因素OpenFeign 默认情况下是不会自动开启超时重试的,所以想要开启超时重试,需要通过以下2 步来实现:

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

3.1 配置超时重试

spring:application:name: nacos-consumer-democloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosregister-enabled: false # 消费者(不需要将此服务注册到nacos)openfeign:client:config:default:connect-timeout: 1000 # 连接超时时间read-timeout: 1000 # 读取超时时间retryer: com.example.consumer.config.CustomRetryer
server:port: 8080

在这里插入图片描述

3.2 覆盖 Retryer

在这里插入图片描述

@Configuration // 将当前对象存储在 IoC 容器
public class RetryerConfig {@Beanpublic Retryer retryer(){return new Retryer.Default(1000,1000,3);}
}

4.自定义超时重试机制

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

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

4.1 自定义超时重试类

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

  1. 固定间隔重试:每次重试之间的时间间隔固定不变,例如每次重试之间相隔1秒。
  2. 指数重试:每次重试之间的时间间隔按指数递增。例如,初始间隔为1秒,每次重试后加倍,即第一次1 秒,第二次 2 秒,第三次 4秒,以此类推。
  3. 随机间隔重试:每次重试之间的时间间隔是随机的,通过引入随机性来防止多个失败请求同时发生。例如,每3.次重试的时间间隔在一定范围内随机选择。
    在这里插入图片描述
package com.example.consumer.config;import feign.RetryableException;
import feign.Retryer;import java.time.LocalDateTime;/*** 自定义超时重传类*/
public class CustomRetryer implements Retryer {private final int maxAttempts;  // 最大尝试次数private final long backoff;     // 超时间隔时间int attempt; // 当前尝试次数public CustomRetryer() {this.maxAttempts = 3;this.backoff = 1000L;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) {throw new RuntimeException(ex);}}@Overridepublic Retryer clone() {return new CustomRetryer();}
}

4.2 设置配置文件

spring:application:name: nacos-consumer-democloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosregister-enabled: false # 消费者(不需要将此服务注册到nacos)openfeign:client:config:default:connect-timeout: 1000 # 连接超时时间read-timeout: 1000 # 读取超时时间retryer: com.example.consumer.config.CustomRetryer
server:port: 8080

5.超时重试底层实现

在这里插入图片描述

5.1 超时底层实现

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

5.2 重试底层实现

  @Overridepublic Object invoke(Object[] argv) throws Throwable {RequestTemplate template = buildTemplateFromArgs.create(argv);Options options = findOptions(argv);Retryer retryer = this.retryer.clone();try {if (methodInfo.isAsyncReturnType()) {return executeAndDecode(template, options, retryer);} else {return executeAndDecode(template, options, retryer).join();}} catch (CompletionException e) {throw e.getCause();}}private CompletableFuture<Object> executeAndDecode(RequestTemplate template,Options options,Retryer retryer) {CancellableFuture<Object> resultFuture = new CancellableFuture<>();executeAndDecode(template, options).whenComplete((response, throwable) -> {if (throwable != null) {if (!resultFuture.isDone() && shouldRetry(retryer, throwable, resultFuture)) {if (logLevel != Logger.Level.NONE) {logger.logRetry(metadata.configKey(), logLevel);}resultFuture.setInner(executeAndDecode(template, options, retryer));}} else {resultFuture.complete(response);}});return resultFuture;}
/** Copyright 2012-2022 The Feign Authors** Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except* in compliance with the License. You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software distributed under the License* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express* or implied. See the License for the specific language governing permissions and limitations under* the License.*/
package feign;import static java.util.concurrent.TimeUnit.SECONDS;/*** Cloned for each invocation to {@link Client#execute(Request, feign.Request.Options)}.* Implementations may keep state to determine if retry operations should continue or not.*/
public interface Retryer extends Cloneable {/*** if retry is permitted, return (possibly after sleeping). Otherwise propagate the exception.*/void continueOrPropagate(RetryableException e);Retryer clone();class Default implements Retryer {private final int maxAttempts;private final long period;private final long maxPeriod;int attempt;long sleptForMillis;public Default() {this(100, SECONDS.toMillis(1), 5);}public Default(long period, long maxPeriod, int maxAttempts) {this.period = period;this.maxPeriod = maxPeriod;this.maxAttempts = maxAttempts;this.attempt = 1;}// visible for testing;protected long currentTimeMillis() {return System.currentTimeMillis();}public void continueOrPropagate(RetryableException e) {if (attempt++ >= maxAttempts) {throw e;}long interval;if (e.retryAfter() != null) {interval = e.retryAfter().getTime() - 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;}sleptForMillis += interval;}/*** Calculates the time interval to a retry attempt. <br>* The interval increases exponentially with each attempt, at a rate of nextInterval *= 1.5* (where 1.5 is the backoff factor), to the maximum interval.** @return time in milliseconds from now until the next attempt.*/long nextMaxInterval() {long interval = (long) (period * Math.pow(1.5, attempt - 1));return interval > maxPeriod ? maxPeriod : interval;}@Overridepublic Retryer clone() {return new Default(period, maxPeriod, maxAttempts);}}/*** Implementation that never retries request. It propagates the RetryableException.*/Retryer NEVER_RETRY = new Retryer() {@Overridepublic void continueOrPropagate(RetryableException e) {throw e;}@Overridepublic Retryer clone() {return this;}};
}

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

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

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

相关文章

golang通过go-aci适配神通数据库

1. go-aci简介 go-aci是神通数据库基于ACI(兼容Oracle的OCI)开发的go语言开发接口&#xff0c;因此运行时需要依赖ACI驱动和ACI库的头文件。支持各种数据类型的读写、支持参数绑定、支持游标范围等操作。 2. Linux部署步骤 2.1. Go安装&#xff1a; 版本&#xff1a;1.9以上…

【从C++到Java一周速成】章节14:网络编程

章节14&#xff1a;网络编程 【1】网络编程的概念【2】IP地址与端口的概念【3】网络通信协议引入网络通信协议的分层 【3】Socket套接字【4】单向通信【5】双向通信 【1】网络编程的概念 把分布在不同地理区域的计算机与专门的外部设备用通信线路互联成一个规模大、功能强的网…

头歌openGauss-存储过程第2关:修改存储过程

任务描述 本关任务&#xff1a; 修改存储过程pro0101&#xff0c;并调用&#xff1b; --修改sel_course表中成绩<60的记录为成绩10&#xff0c;然后将计算机学院所有学生的选课成绩输出&#xff1b; --a、需要先删除存储过程pro0101&#xff1b; drop procedure if exists p…

LLM 入门与实践(三)Baichuan2 部署与分析

本文截取自20万字的《PyTorch实用教程》&#xff08;第二版&#xff09;&#xff0c;敬请关注&#xff1a;《Pytorch实用教程》&#xff08;第二版&#xff09;《Pytorch实用教程》&#xff08;第二版&#xff09;无论是零基础入门&#xff0c;还是CV、NLP、LLM项目应用&#x…

Python协程的作用

过分揣测别人的想法&#xff0c;就会失去自己的立场。大家好&#xff0c;当代软件开发领域中&#xff0c;异步编程已成为一种不可或缺的技术&#xff0c;用于处理大规模数据处理、高并发网络请求、实时通信等应用场景。而Python协程&#xff08;Coroutine&#xff09;作为一种高…

【译】MySQL 组复制 - 部分网络故障对性能的影响

原文地址&#xff1a;MySQL Group Replication – Partial Network Failure Performance Impact 在这个由两部分组成的博客系列中&#xff0c;我想介绍一些使用组复制的故障转移场景。在第一部分中&#xff0c;我将讨论我在撰写这些文章时发现的一种有趣的行为和性能下降。在第…

C#学习指南:重要内容与实用技巧

学习C#编程是一段充满挑战但又非常充实的旅程。以下是我在学习过程中积累的一些经验&#xff0c;希望能对大家有所帮助。 一、掌握基础概念 类及其成员 C#中的类是编程的基础模块。理解类的结构、属性、方法和构造函数是至关重要的。每个类都有其特定的功能&#xff0c;学会如…

力扣HOT100 - 169. 多数元素

解题思路&#xff1a; 有点类似于Boyer-Moore 投票算法&#xff0c;但更加形象。 class Solution {public int majorityElement(int[] nums) {int winner nums[0];int cnt 1;for (int i 1; i < nums.length; i) {if (winner nums[i]){cnt;} else if (cn…

景源畅信数字:抖音小店新手该怎么做?

在数字化时代的浪潮中&#xff0c;抖音不仅仅是一个分享短视频的平台&#xff0c;更是一个充满潜力的电商平台。对于想要进入这个领域的朋友们来说&#xff0c;开设一家抖音小店无疑是一个既激动又迷茫的起点。那么&#xff0c;作为新手&#xff0c;该如何在这个全新的舞台上立…

【Linux】信号之信号的产生详解

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64f;如果内容有误的话&#xff0c;还望指出&…

vue核心模块源码解析

响应式原理 Object.definePropertysetterProxy var count 1 var state {} Object.defineProperty(state , count,{get(){return count},set(val){count val} }) //弊端&#xff1a;不能主动监听到对象属性的新增或者删除&#xff0c;add/deleteref和reactive 声明响应式数…

翻译《The Old New Thing》- How do I mark a shortcut file as requiring elevation?

How do I mark a shortcut file as requiring elevation? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20071219-00/?p24103 Raymond Chen 2007年12月19日 如何将快捷方式标记为需要提升权限 简要 文章介绍了如何通过设置SLDF_RUNAS_US…

许冉直播不治本,京东需要刘强东

图片&#xff5c;影视剧《纸牌屋》剧照 ©自象限原创 作者丨艾AA 编辑丨薛黎 这届618&#xff0c;消费者的热情还未显现&#xff0c;商家的怒火先爆发了。 5月21日京东618开幕次日&#xff0c;多家图书社抵制618图书大促登上了热搜。此次争议与去年双十一京东采销与电…

移动端h5适配方案:媒体查询、编写js、lib-flexible、vw、rem和vw单位换算

文章目录 各种方案第二种&#xff1a;动态设置html的font-size媒体查询mediajs 第三种&#xff1a;vw方案 rem、vw单位换算手动根据设计稿进行计算lessvs code 插件 各种方案 1&#xff09;百分比设置&#xff08;X&#xff09;【百分比很难统一&#xff0c;不推荐】 2&#xf…

安卓高级控件(下拉框、列表类视图、翻页类视图、碎片Fragment)

下拉框 此小节介绍下拉框的用法以及适配器的基本概念&#xff0c;结合对下拉框Spinner的使用说明分别阐述数组适配器ArrayAdapter、简单适配器SimpleAdapter的具体用法与展示效果。 下拉框控件Spinner Spinner是下拉框控件&#xff0c;它用于从一串列表中选择某项&#xff0…

Java与GO语言对比分析

你是不是总听到go与java种种对比&#xff0c;其中在高并发的服务器端应用场景会有人推荐你使用go而不是 java。 那我们就从两者运行原理和基本并发设计来对比分析&#xff0c;看看到底怎么回事。 运行原理对比 java java 中 jdk 已经帮我们屏蔽操作系统区别。 只要我们下载并…

Android中华为手机三态位置权限申请理解

博主前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住也分享一下给大家&#xff0c; &#x1f449;点击跳转到教程 前言&#xff1a; 使用的华为MATE 20,Android10的系统。 <!--精准定位权限&#xff0c;如&#xff1a;…

“闻起来有股答辩的味道”,答辩到底是什么味?

“闻起来有股答辩的味道”&#xff0c;答辩到底是什么味&#xff1f; 一位名叫“小鸡全家桶”的作者虚构了这样一个学校故事&#xff0c;故事说&#xff0c;由于学生的考试试卷印刷得特别模糊&#xff0c;导致里面的插图根本看不清&#xff0c;学生感到懵逼&#xff0c;监考老…

【区块链】智能合约漏洞测试

打开Ganache vscode打开智能合约漏洞工程 合约内容 pragma solidity >0.8.3;contract EtherStore {mapping(address > uint) public balances;function deposit() public payable {balances[msg.sender] msg.value;emit Balance(balances[msg.sender]);}function with…

深度学习之基于Tensorflow卷积神经网络(CNN)实现猫狗识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 在人工智能和深度学习的热潮中&#xff0c;图像识别是一个备受关注的领域。猫狗识别作为图像识…