Spring Cloud2022之OpenFeign使用以及部分源码分析

OpenFeign使用

Feign和OpenFeign

Feign是Netflix开发的⼀个轻量级RESTful的HTTP服务客户端,可以使用⽤它来发起请求,进行远程调用。Fegin是以Java接口注解的⽅式调⽤Http请求,而不是像RestTemplate那样,在Java中通过封装HTTP请求报⽂的⽅式直接调用。
Feign可帮助我们更加便捷,优雅的调⽤HTTP API:不需要我们去拼接url然后调⽤restTemplate的api,但是Fegin的缺点缺点,它不支持SpringMVC的注解。

Spring Cloud在Feign的基础上进行了封装,从而有了OpenFeign。
Feign githup主页

OpenFeign的使用

OpenFeign的使用非常简单,只需要在服务调用方创建远程调用接口,然后创建和被调用方方法一样的方法,最后在需要使用的地方导入远程调用接口,调用接口的方法即可发起请求了。

在pom文件中添加OpenFeign的依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

在调用方服务的启动类上添加@EnableFeignClients注解

@SpringBootApplication
@EnableFeignClients  //开启Feign的功能
public class Conuserservice01Application {

    public static void main(String[] args) {
        try {
            SpringApplication.run(Conuserservice01Application.class, args);
        } catch (Exception e) {
            System.out.println("e.getMessage() = " + e.getMessage());
        }

    }

}

创建远程调用接口

@FeignClient("providerservice")  //指定要调用的服务需要和被调用的服务的application.name保持一致
public interface ProviderServiceClient {


    //要调用的服务中的请求,需要被调用的服务中的请求方法保持一致
    @GetMapping("/user/{userId}")
    public String getUserById(@PathVariable("userId") String userId);

}

在Controller中使用远程调用接口

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private ProviderServiceClient client;

    @RequestMapping("/{userId}")
    public String getUserById(@PathVariable String userId) {
        LOGGER.info("userId: " + userId);
        String user = client.getUserById(userId);
        return user;
    }
}

访问/consumer/1的请求,会远程调用providerservice服务实例中请求路径为/user/{userId}的请求。
在这里插入图片描述

providerservice服务中被访问的请求,这个请求的方法要和远程调用接口中的方法保持一致。

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

    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

    @GetMapping("/{userId}")
    public String getUserById(@PathVariable String userId) {
        LOGGER.info("userId: " + userId);
        return "user1";
    }
}

Feign的相关配置

Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:
在这里插入图片描述
一般我们只需要修改日志级别即可。

日志级别

Feign的日志级别有如下几种:

  • NONE:默认的,不显示任何⽇志,性能最好;
  • BASIC:仅记录请求⽅法、URL、响应状态码以及执⾏时间----⽣产问题追踪;
  • HEADERS:在BASIC级别的基础上,记录请求和响应的header;
  • FULL:记录请求和响应的header、body和元数据,适⽤于开发及测试环境定位问题;

覆盖Feign默认的配置有两个维度,一个是为每个FeignClient单独配置(局部配置),另一个是全局配置;下面先来看局部配置。不过要先在yml中设置SpringBoot的日志输出级别

logging:
  level:
    # Feign⽇志只会对⽇志级别为debug的做出响应,这里需要设置SpingBoot的日志级别为debug,否则不会输出feign的日志;因为springBoot日志级别默认为info,这里把ProviderServiceClient接口的日志级别设置为了debug,也可以设置指定目录的日志级别
    com.example.conuserservice01.client.ProviderServiceClient: debug
局部配置日志级别

在application.yml文件中配置日志级别

logging:
  level:
    # ProviderServiceClient接口的方法的日志级别为debug,其它接口的不会生效
    com.example.conuserservice01.client.ProviderServiceClient: debug

通过@FeignClient注解的configuration属性指定日志配置

@FeignClient(value = "providerservice", contextId = "providerservice",  configuration = FeignConfig.class)  //指定要调用的服务
public interface ProviderServiceClient {


    //要调用的服务中的请求,需要被调用的服务中的请求方法保持一致
    @GetMapping("/user/{userId}")
    public String getUserById(@PathVariable("userId") String userId);

}

日志配置类

public class FeignConfig {

    @Bean
    Logger.Level feignLevel() {
        return Logger.Level.FULL;
    }

}
全局配置日志级别

全局配置日志级别可以使用yml文件配置,也可以使用配置文件进行配置。
这里如果使用服务名称则是全局配置,如果使用contextId,则是针对指定的FeignClient接口的单独配置;

spring:
  cloud:
    openfeign:
      client:
        config:
          providerservice: # 如果FeignClient注解设置了contextId这里就使用contextId如,果没有设置contextId就使用服务名称
            loggerLevel: full

使用配置类

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLevel() {
        return Logger.Level.FULL;
    }

}

负载均衡

Cloud 2020.0.X版本开始OpenFeign底层不再使用Ribbon了。所以在配置负载均衡的时候使用之前的方式是不行的。

这里使用的注册中心是Nacos,最后走的是NacosLoadBalancer。choose方法就是根据负载均衡算法选择一个服务实例进行访问。

我们在浏览器输入地址访问,然后调用远程接口访问,会执行到SynchronousMethodHandler的invoke方法。这里面executeAndDecode方法会选择服务实例,发起请求。continueOrPropagate方法则是请求出现问题后的重试。

在这里插入图片描述

在这里插入图片描述

选择服务实例并发送请求的执行流程如下:
在这里插入图片描述

这里会通过choose方法拿到服务实例,最后执行的是NacosLoadBalancer中的choose方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这里就完成了获取服务实例的过程。

发送请求的代码在获取到服务实例的步骤后面。
在这里插入图片描述
然后会执行到LoadBalancerUtils的executeWithLoadBalancerLifecycleProcessing方法,通过feignRequest的url可以看到,这个时候已经将服务名转成了根据负载均衡算法选择到的服务实例的ip和端口号
在这里插入图片描述

在这里插入图片描述

最后可以看到是通过HttpURLConnection发送的请求。
在这里插入图片描述

请求压缩和响应压缩

OpenFeign⽀持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。可以在yml文件中配置请求压缩和响应压缩

spring:
  cloud:
    openfeign:
      compression:
        request:
          enabled: true #开启请求压缩
          min-request-size: 2048  #设置触发压缩的大小下限,此处也是默认值
          mime-types: text/html,application/xml,application/json #设置压缩的数据类型,此处也是默认值
        response:
          enabled: true #开启响应压缩

对熔断器的支持

性能优化

通过前面前面的分析可以看到OpenFeign底层使用的是HttpURLConnection发送的请求,但是它不支持连接池。因此主要是针对这一点进行优化。
在这里插入图片描述

OpenFeign使用Apache HttpClient客户端

加入htppClient和feign-httpclient的依赖,feign-httpclient的version要和openfeign-core的version保持一致。

        <!-- 使用Apache HttpClient替换Feign原生httpURLConnection -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
            <version>12.1</version>
        </dependency>

开启httpClient的支持,默认是开启的。

spring:
  cloud:
    openfeign:
      httpclient:
        enabled: true

注入Apache HttpClient


    @Bean
    public ApacheHttpClient getApacheHttpClient() {
        return new ApacheHttpClient();
    }

到这里使用Apache HttpClient的配置就完成了。

使用Apache HttpClient的原理如下:
在这里插入图片描述

在这里插入图片描述

参考

  1. Spring Cloud OpenFeign
  2. Spring Cloud OpenFeign - - - > 日志级别配置
  3. SpringCloud OpenFeign 全功能配置详解
  4. Cloud 2020.0.X版本开始OpenFeign底层不再使用Ribbon
  5. 源码分析及实践测试OpenFeign负载均衡
  6. springcloud-Feign-HttpClient连接池(提升 Feign 的并发吞吐量)
  7. Nacos负载均衡策略
  8. 怎样配置Feign使用HttpClient

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

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

相关文章

【茶话数据结构】查找最短路径——Dijkstra算法详解(保姆式详细图解,步步紧逼,保你学会)

&#x1f4af; 博客内容&#xff1a;【茶话数据结构】查找最短路径——Dijkstra算法详解 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f989;所属专栏&#xff1a;数据结构笔记 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准前端&#xff0c;专注基础和实…

d3dcompiler_47.dll丢失的解决方法

d3dcompiler_47.dll 是一个属于 Microsoft DirectX 软件组件的动态链接库 (DLL) 文件。DirectX 是微软开发的一套广泛应用于 Windows 操作系统上的应用程序接口 (API)&#xff0c;主要用于处理多媒体、特别是与游戏和高级图形相关的任务&#xff0c;例如二维 (2D) 和三维 (3D) …

Aigtek高精度电流源仪器设计规范

高精度电流源仪器是一种用于产生和测量精确电流的设备&#xff0c;广泛应用于电子、通信、自动控制等领域。为了确保仪器的性能和可靠性&#xff0c;设计过程中需要遵循一些规范。 电流源仪器的设计要注重稳定性。稳定性是保证仪器输出电流精度的关键因素。设计过程中应选择高精…

稀疏图带负边的全源最短路Johnson算法

BellmanFord算法 Johnson算法解决的问题 带负权的稀疏图的全源最短路 算法流程 重新设置的每条边的权重都大于或等于0&#xff0c;跑完Djikstra后得到的全源最短路&#xff0c;记得要还原&#xff0c;即&#xff1a;f(u,v) d(u,v) - h[u] h[v] 例题

vue 解决:点击左侧相同菜单,右侧页面不重新加载的问题

1、问题描述&#xff1a; 其一、需求为&#xff1a; 无论是通过路由组件形成的平台管理系统&#xff0c;还是通过文件配置形成的平台管理系统&#xff0c;都存在通过切换左侧的导航栏而使右侧的页面切换的业务需求&#xff1b; 其二、问题描述为&#xff1a; A、步骤一&#…

【Unity】如何在Unity 中创建带有缩放效果的滚动视图(具有吸附效果的实现与优化)?

效果预览&#xff1a; 目录 效果预览&#xff1a; 一、引言&#xff1a; 二、问题描述 三、解决方案&#xff1a; 三、优化&#xff1a; 四、结论 一、引言&#xff1a; 在Unity开发中&#xff0c;经常需要实现滚动视图&#xff08;ScrollView&#xff09;中的内容吸附到…

印象笔记 - Markdown 入门指南

一、Markdown 是什么&#xff1f; Markdown 是一种轻量级的「标记语言」&#xff0c;创始人为约翰格鲁伯&#xff0c;用简洁的语法代替排版&#xff0c;目前被越来越多的知识工作者、写作爱好者、程序员或研究员广泛使用。其常用的标记符号不超过十个&#xff0c;相对于更为复…

一张图读懂人工智能

一、生成人工智能的概念和应用&#xff0c;以及如何使用大型语言模型进行聊天和创造原创内容。这项技术将会对人类和企业产生深远影响。 计算机获得学习、思考和交流的能力&#xff0c;被称为生成人工智能。生成人工智能可以立即获得人类所有知识的总和&#xff0c;并回答任何…

【Intel oneAPI实战】使用英特尔套件解决杂草-农作物检测分类的视觉问题

目录 一、简介&#xff1a;计算机视觉挑战——检测并清除杂草二、基于YOLO的杂草-农作物检测分类2.1、YOLO简介2.2、基于YOLO的杂草-农作物检测分类解决方案 三、基于YOLO的杂草-农作物检测分类系统设计3.1、基于flask框架的demo应用程序后端3.2、基于Vue框架的demo应用程序前端…

c++中使用lambda表达式的作用和用法

lambda表达式&#xff1a; 这是C11引入的一种新特性&#xff0c;它可以让您在需要定义函数对象的地方&#xff0c;直接编写一个匿名的、可以捕获上下文变量的函数体&#xff0c;非常适合用作回调函数、临时计算或定义小型函数对象。 lambda表达式与普通函数类似&#xff0c;也有…

[MYSQL数据库]--mysql的基础知识

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、数据库…

上门废品回收小程序开发,从传统到线上,到“高收益”

随着我国社会经济不断发展&#xff0c;人们的消费水平能力也在不断提升&#xff0c;日常生活中会产生非常多的废弃物品&#xff0c;为废品回收行业带来了大量的机遇。在回收行业的发展前景下&#xff0c;也为年轻人带来了创业机会&#xff0c;既获得利润&#xff0c;也能为社会…

六、OpenAI之嵌入式(Embedding)

嵌入模式 学习怎么将文本转换成数字&#xff0c;解锁搜索等案例。 新的嵌入模型 text-embedding-3-small 和 text-embedding-3-large&#xff0c;是目前最新的并且性能最好的嵌入模型&#xff0c;成本低&#xff0c;支持多语言&#xff0c;拥有控制所有大小的新参数 1. 什么是…

周鸿祎免费课演示AI新品,瞬时流量暴增现场增加服务器

2月29日&#xff0c;360创始人周鸿祎首堂AI免费课开讲&#xff0c;吸引千万网友围观。演讲现场周鸿祎演示了两款AI驱动的新产品。在演示测试版360AI搜索时&#xff0c;由于用户体验火爆&#xff0c;瞬时流量暴增44倍&#xff0c;为满足用户和全网用户需求临时增加了服务器。产品…

solidity编程

一.Solidity 简介 Solidity 是⼀种⽤于编写以太坊虚拟机&#xff08; EVM &#xff09;智能合约的 编程语⾔。我认为掌握 Solidity 是参与链上项⽬的必备技 能&#xff1a;区块链项⽬⼤部分是开源的&#xff0c;如果你能读懂代码&#xff0c;就可以 规避很多亏钱项⽬。…

LeetCode 2265.统计值等于子树平均值的节点数

给你一棵二叉树的根节点 root &#xff0c;找出并返回满足要求的节点数&#xff0c;要求节点的值等于其 子树 中值的 平均值 。 注意&#xff1a; n 个元素的平均值可以由 n 个元素 求和 然后再除以 n &#xff0c;并 向下舍入 到最近的整数。 root 的 子树 由 root 和它的所…

大模型量化技术原理-ZeroQuant系列

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;从而导致模型变得越来越大&#xff0c;因此&#xff0c;我们需要一些大模型压缩技术来降低模型部署的成本&#xff0c;并提升模型的推理性能。 模型压缩主要分…

什么是VR紧急情况模拟|消防应急虚拟展馆|VR游戏体验馆加盟

VR紧急情况模拟是利用虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术来模拟各种紧急情况和应急场景的训练和演练。通过VR技术&#xff0c;用户可以身临其境地体验各种紧急情况&#xff0c;如火灾、地震、交通事故等&#xff0c;以及应对这些紧急情况的…

IM(即时通讯-聊天工具):一文读懂,技术栈和界面设计。

大家好&#xff0c;我是贝格前端工场&#xff0c;本期继续分享IM&#xff08;即时通讯&#xff09;的设计&#xff0c;欢迎大家关注&#xff0c;如有B端写系统界面的设计和前端需求&#xff0c;可以联络我们。 一、什么是IM&#xff08;聊天工具) IM即时通讯工具是指一类用于…

C++——类和对象(2):构造函数、析构函数、拷贝构造函数

2. 类的6个默认成员函数 我们将什么成员都没有的类称为空类&#xff0c;但是空类中并不是什么都没有。任何类中都会存在6个默认成员函数&#xff0c;这6个默认成员函数如果用户没有实现&#xff0c;则会由编译器默认生成。 6个默认成员函数包括&#xff1a;负责初始化工作的构造…