http 客户端 Feign【微服务】

文章目录

    • 1. 基于 Feign 的远程调用
    • 2. Feign 自定义配置
    • 3. Feign 性能优化
    • 4. Feign 的最佳实践
      • 4.1 继承
      • 4.2 抽取

1. 基于 Feign 的远程调用

Feign 是一个声明式的 http 客户端,它可以帮助我们优雅地发送 http 请求。

在学习 Feign 之前先来看一下我们以前利用 RestTemplate 是如何发起远程调用请求的。

String url = "http://userserver/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);

存在下面的问题:
① 代码可读性差,编程体验不统一;
② 对于参数复杂的 URL 难以维护。

使用 Feign 的步骤如下:

① 引入依赖

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

在这里插入图片描述

② 在启动类上添加注解 @EnableFeignClients,开启自动装配功能

在这里插入图片描述

③ 编写 user 客户端做接口声明,我们就可以通过调用该接口里面的方法,来向 user 服务端(userserver)发起 http 请求

package com.zxe.orderserver.clients;

import com.zxe.orderserver.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

//指定请求的服务名称
@FeignClient("userserver")
public interface UserClient {

    //指定请求路径及请求方式
    @GetMapping("/user/{id}")
    //方法的返回值就是最终请求到的结果
    User findById(@PathVariable("id") Long id);
}

在这里插入图片描述

在这里插入图片描述

④ 使用客户端,直接调用 UserClient 中的方法完成远程调用

在这里插入图片描述

⑥ 添加负载均衡依赖,Feign 内部已经集成了 Ribbon 负载均衡规则,可以直接实现负载均衡

在这里插入图片描述

⑦ 启动项目测试一下,可以看到我们已经实现了远程调用

在这里插入图片描述

2. Feign 自定义配置

Feign 运行自定义配置来覆盖默认配置,一般我们需要配置的就是日志级别。

在这里插入图片描述

配置 Feign 日志有两种方式:

① 配置文件方式

default代表全局配置,也可以把 default 换成具体的服务名,就是局部配置!

#配置Feign日志
feign:
  client:
    config:
      default: 
        logger-level: Full

启动项目,可以看到完整的日志信息:

在这里插入图片描述

② Java 代码方式

需要先声明一个 Bean:

package com.zxe.orderserver.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;

public class DefaultFeignConfiguration {
    @Bean
    public Logger.Level logLevel() {
        return Logger.Level.BASIC;
    }
}

在这里插入图片描述

在这里插入图片描述

如果是全局配置,则把它放到启动类的 @EnableFeignClients 注解中;如果是局部配置,就把它放到 @FeignClient 这个注解中。

在这里插入图片描述

在这里插入图片描述

日志记录还是需要消耗一些性能的,所以日志级别我们一般用 BASIC 就可以了!

3. Feign 性能优化

Feign 是一个声明式客户端,它只是把我们的声明变成一个 http 请求,而最终发起 http 请求的其实是其它的客户端,默认用的是 URLConnection。

Feign 底层的客户端实现:
① URLConnection:默认实现,不支持连接池;
② Apache HttpClient:支持连接池;
③ OKHttp:支持连接池。

URLConnection 不支持连接池,那么每次连接与断开都需要经历三次握手和四次挥手,对性能的损耗是比较大的,因此我们可以使用另外两种客户端来代替默认的 URLConnection。

因此 Feign 的性能优化主要包括以下两点:
① 使用连接池代替默认的 URLConnection;
② 日志级别,最好用 basic 或 none。

① 引入 HttpClient 依赖

Spring 已经管理了 HttpClient,所以不需要加版本号!

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

在这里插入图片描述

② 开启 Feign 对 HttpClient 的支持,并配置连接池

最大连接数的设置要根据真实情况去设置!

feign:
  httpclient:
    enabled: true #开启Feign对HttpClient的支持
    max-connections: 200 #最大连接数
    max-connections-per-route: 50 #单个路径的最大连接数

4. Feign 的最佳实践

4.1 继承

仔细观察你会发现,UserClient 中的 findById 和 UserController 的 findById 方法是一模一样的,因为一个是客户端一个是服务端,想要建立连接,访问路径肯定是完全一样的。既然是重复的东西,写两遍会不会有点冗余?

在这里插入图片描述

在这里插入图片描述

解决办法就是给消费者的 FeignClient 和提供者的 controller 定义统一的父接口作为标准。

但是在两个独立的微服务之间共享接口,肯定是不合理的,因为这会造成紧耦合。而且方法参数是无法继承的,也就是说 controller 接口还得自己实现 findById。虽然它有这么多的缺点,但是它遵循的是面向契约的思想,使用的还是比较多的。

4.2 抽取

比如 A 服务会用到 userserver,B 服务也会用到 userserver,这时候 A 和 B 服务中都需要编写 FeignClient 代码,且这个代码是完全一样的,那么就没必要写两次了。

所以我们可以将 FeignClient 抽取为独立模块(feign-api),并且把接口相关的 POJO、默认的 Feign 配置也都放到这个模块中,提供给所有消费者使用,消费者之间引依赖远程调用即可。

抽取方式的耦合度就很低了,但是它也有自己的缺点。其实 feign-api 里面不止放 userserver 的客户端,还会放大量的其它微服务的客户端,这时我们只想使用某一个,却把所有的都给引进来了,当然没有一个解决办法是完美的,我们需要根据实际情况选择合适的解决办法。

① 创建一个 module,命名为 feign-api,然后引入 feign 的 starter 依赖

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

② 将 orderserver 中编写的 UserClient、User、DefaultFeignConfiguration 都复制到 feign-api 项目中,记得把包名也改成 feignapi

在这里插入图片描述

在这里插入图片描述

③ 在 orderserver 中引入 feign-api 的依赖,并把刚刚复制到 feign-api 的内容都删掉

<dependency>
    <groupId>com.zxe</groupId>
    <artifactId>feign-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

在这里插入图片描述

④ 修改 orderserver 中的所有与上述三个组件有关的 import 部分,改成导入 feign-api 中的包

在这里插入图片描述

⑤ 单独指定需要加载的客户端,因为启动 orderserver 的时候并不会加载 feign-api 下的包,会报错

在这里插入图片描述

⑥ 重启测试

在这里插入图片描述

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

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

相关文章

SpringBoot3多数据源动态切换

demo使用的时SpringBoot3.x、JDK17、MybatisPlus3.5.x、MySQL8 从数据中加载数据源 定义接口&#xff0c;指定数据源&#xff0c;从不同数据库获取数据 创建数据源表&#xff0c;用于指定不同数据源&#xff0c;程序自动动态获取 项目版本依赖关系 demo中所用到的工具以及…

学习笔记16——操作系统

学习笔记系列开头惯例发布一些寻亲消息&#xff0c;感谢关注&#xff01; 链接&#xff1a;https://www.mca.gov.cn/lljz/indexdetail.html?idd0afa7f6f36946319a206d61937f9b63&type0&t10.11199120579373845 八股——操作系统一些基础知识整理 一个java程序对应一个…

算法32:针对算法31货币问题进行扩展,并对从左往右模型进行总结

本算法是在算法31的基础之上进行推理总结的&#xff0c;因此&#xff0c;在看本章之前&#xff0c;必须先去了解算法31&#xff0c;否则会觉得莫名其妙。 算法31的推理过程&#xff1a; 如果 x y1 y2 y3 y4 y5 y6. x1 y2 y3 y4 y5 y6 那么 x y1 x1. 根据以…

计算机缺失vcomp120.dll文件怎么办?总结多种解决方法分享

在使用电脑过程中&#xff0c;难免会遇到各种问题&#xff0c;其中vcomp120.dll丢失问题就是其中之一。这个问题可能会给用户带来诸多不便&#xff0c;导致某些应用程序无法正常运行。在这篇文章中&#xff0c;我们将详细介绍vcomp120.dll文件的重要性&#xff0c;以及遇到丢失…

使用 vue-json-viewer 工具在界面显示json格式数据

安装vue-json-viewer npm install vue-json-viewer --save 引入&#xff1a; import JsonViewer from vue-json-viewer Vue.use(JsonViewer) 使用&#xff1a; <json-viewer :value"jsonData" show-double-quotes :preview-mode"true" :show-array…

存储器进化全解析:从NAND到UFS,深入剖析常见存储技术与应用

存储领域发展至今&#xff0c;已有很多不同种类的存储器产品。下面给大家介绍几款常见的存储器及其应用&#xff1a;#存储器#​ 一、NAND NAND Flash存储器是Flash存储器的一种&#xff0c;属于非易失性存储器&#xff0c;其内部采用非线性宏单元模式&#xff0c;为固态大容量…

mmdetection训练自己的数据集

mmdetection训练自己的数据集 这里写目录标题 mmdetection训练自己的数据集一&#xff1a; 环境搭建二&#xff1a;数据集格式转换(yolo转coco格式)yolo数据集格式coco数据集格式yolo转coco数据集格式yolo转coco数据集格式的代码 三&#xff1a; 训练dataset数据文件配置config…

C#,迭代深化搜索(IDS)或迭代深化深度优先搜索(IDDFS)算法的源代码

摘要&#xff1a;本文介绍适合于大数据规模情况下的&#xff0c;新型的迭代深化深度优先搜索(IDDFS)算法的原理、实例及实现的C#源代码。 引言 常用的树&#xff08;或图&#xff09;遍历算法是两种&#xff1a; 广度优先搜索算法&#xff08;BFS&#xff09; 和 深度优先搜索…

C#编程-实现文件输入和输出操作

实现文件输入和输出操作 所有程序接受用户的输入、处理输入并且产生输出。所以,所有的编程语言都支持输入和输出操作。例如,您需要为教师开发程序以接受学生的结果信息。您的程序应该将信息保存在硬盘的Result.xls文件中。您可以在程序中使用文件输入和输出操作以接受来自教…

外汇网站主要业务逻辑梳理

上图为工行ICBC的外汇保证金交易界面。 当需要买入帐户欧元&#xff08;欧元人民币&#xff09;时&#xff0c;买入100欧元&#xff0c;因为没有杠杆&#xff0c;虽然欧元中间价是782.34&#xff0c;但实际需要支付783.14元人民币的保证金&#xff0c;这个兑换不是真实的外汇兑…

全网独家:基于openeuler-20.03-lts底包构建opengauss数据库V5.0.1LTS的单机容器

近期想测试一下opengauss数据库,官网上单机容器部署只有x86-64平台CentOS 7.6和ARM64平台 openEuler20.03 LTS两种底包方案。本文系全网独家在x86平台上基于openeuler-20.03-lts底包构建opengauss数据库V5.0.1LTS的单机容器。 opengauss官网上单机容器部署只有x86-64平台Cent…

计算机毕业设计 基于javaweb的学生交流培养管理平台/系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

910b上跑Chatglm3-6b进行流式输出【pytorch框架】

文章目录 准备阶段避坑阶段添加代码结果展示 准备阶段 配套软件包Ascend-cann-toolkit和Ascend-cann-nnae适配昇腾的Pytorch适配昇腾的Torchvision Adapter下载ChatGLM3代码下载chatglm3-6b模型&#xff0c;或在modelscope里下载 避坑阶段 每个人的服务器都不一样&#xff0…

Unity3d 实现直播功能(无需sdk接入)

Unity3d 实现直播功能 需要插件 :VideoCapture 插件地址(免费的就行) 原理:客户端通过 VideoCapture 插件实现推流nodejs视频流转服务进行转发,播放器实现rtmp拉流 废话不多说,直接上 CaptureSource我选择的是屏幕录制,也可以是其他源 CaptureType选择LIVE–直播形式 LiveSt…

IDEA[Debug]简单说明

目录 &#x1f95e;1.打断点 &#x1f32d;2.第一组按钮 &#x1f9c2;3.第二组按钮 &#x1f953;4.参数查看 1.打断点 1.在需要断点处打上断点&#xff0c;然后点击debug运行 2.执行debug&#xff0c;直接执行到断点处 2.第一组按钮 共有8按钮&#xff0c;从左往右依…

【系统高级-环境变量】path配置一整行,而不是列表

这是列表编辑方便。但是不知道为什么变成一行&#xff0c;非常的令人抓狂&#xff0c;经过研究发现&#xff0c;第一个环境变量必须为C:\Windows\system32 开头才可以 文章如下 修改环境变量中的一行变成列表形式_环境变量编辑不是列表-CSDN博客

回归预测 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变…

苍穹外卖Day01——总结1

总结1 1. 软件开发整体介绍1.1 软件开发流程1.2 角色分工1.3 软件环境 2. 苍穹外卖项目介绍2.1 项目介绍2.2 技术选项 3. Swagger4. 补充内容&#xff08;待解决...&#xff09; 1. 软件开发整体介绍 1.1 软件开发流程 1.2 角色分工 从角色分工里面就可以查看自己以后从事哪一…

芯片命名大全:完整的器件型号包括主体型号、前缀、后缀等!

不少公司的采购会发现&#xff0c;拿到工程师提供的BOM中的器件去采购物料时&#xff0c;经常供应商还会问得更仔细&#xff0c;否则就不知道供给你哪种物料&#xff0c;严重时&#xff0c;采购回来的物料用不了。为什么会有这种情况呢&#xff1f;问题就在于&#xff0c;很多经…

数据结构—图(下)

文章目录 12.图(下)(4).生成树和最小生成树#1.什么是生成树和最小生成树&#xff1f;i.生成树ii.最小生成树 #2.Prim算法i.算法思想ii.看看例子iii.代码实现 #3.Kruskal算法i.算法思想ii.看看例子iii.代码实现 #4.次小生成树 (5).最短路径问题#1.加权有向图的最短路径问题#2.单…