当前位置: 首页 > news >正文

Feign组件的使用及开发中使用方式

在这里插入图片描述

在微服务的服务集群中服务与服务之间需要调用暴露的服务.那么就需要在服务内部发送http请求, 我们可以使用较为老的HttpClient实现,也可以使用SpringCloud提供的RestTemplate类调用对应的方法来发送对应的请求。

说明:
现在有两个微服务一个是order-service(订单)服务,一个是user-service(用户)服务,在订单服务中需要使用user-service暴露的服务调用方法获取user信息

@Service
public class OrderService {
//    注入 restTemplate 
//    说明: RestTemplate类已经在启动类中通过@Bean注解放入IOC容器, 此时才可以注入,不然空指针@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate OrderMapper orderMapper;public Order queryOrderById(Long orderId) {// 查询订单Order order = orderMapper.findById(orderId);// 拼接地址 String url = "http://user-service/user/"+order.getUserId();// 发送请求User user = restTemplate.getForObject(url, User.class);// 存入order中order.setUser(user);// 返回return order;}
}

RestTemplate方式的优缺点:

优点: 灵活,简单

缺点: 代码可读性差,编程体验不统一 参数复杂URL难以维护

Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign

其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

在这里插入图片描述

一 Feign替代RestTemplate(Feign的使用)

因为Feign的请求地址是从注册中心获取的所以要求对应的服务已向注册中心注册,可看下面这篇笔记

Nacos注册中心一些配置说明_yfs1024的博客-CSDN博客

1. 引入依赖

我们在order-service服务的pom文件中引入feign的依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.7.RELEASE</version>
</dependency>
2. 添加注解

在order-service的启动类添加注解开启Feign的功能:

@SpringBootApplication
@EnableFeignClients
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}
}
3. 编写Feign的客户端

在order-service中新建一个接口,内容如下:

@FeignClient("user-service")  // value为对应的服务名
public interface UserClient {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);
}

这个客户端主要是基于SpringMVC的注解来声明远程调用的信息,比如:

  • 服务名称:user-service
  • 请求方式:GET
  • 请求路径:/user/{id}
  • 请求参数:Long id
  • 返回值类型:User

这样,Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。

@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserClient userClient;public Order queryOrderById(Long orderId) {// 查询订单Order order = orderMapper.findById(orderId);// 调用方法order.setUser(userClient.findById(order.getUserId()));// 返回return order;}
}

这样看起来就十分的优雅, 那么为什么Feign通过服务名称就可以拉取到注册中心的服务呢?在之前介绍Eureka的时候说过一个Ribbon组件,他的作用就是如此. 具体的源码分析在之前的笔记中也有

Eureka注册中心及Ribbon的源码跟踪_yfs1024的博客-CSDN博客

总结

使用Feign的步骤:

① 引入依赖

② 添加@EnableFeignClients注解

③ 编写FeignClient接口

二 Feign的自定义配置

Feign可以支持很多的自定义配置,如下表所示:

类型作用说明
feign.Logger.Level修改日志级别包含四种不同的级别:NONE、BASIC、HEADERS、FULL
feign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象
feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送
feign. Contract支持的注解格式默认是SpringMVC的注解
feign. Retryer失败重试机制请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

一般情况下,默认值就能满足我们使用,如果要自定义时,只需要创建自定义的@Bean覆盖默认Bean即可。

下面以日志为例来演示如何自定义配置。

方式一 配置文件的方式

基于配置文件修改feign的日志级别可以针对单个服务:

feign:  client:config: userservice: # 针对某个微服务的配置loggerLevel: BASIC #  日志级别 

也可以针对所有服务:

feign:  client:config: default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置loggerLevel: BASIC #  日志级别 

日志的级别分为四种:

  • NONE:不记录任何日志信息,这是默认值。
  • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
  • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
  • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
方式二 java代码的方式

先声明一个类,然后声明一个Logger.Level的对象:

public class DefaultFeignConfiguration  {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC; // 日志级别为BASIC}
}

如果要全局生效,将其放到启动类的@EnableFeignClients这个注解中:

@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class) 

如果是局部生效,则把它放到对应的@FeignClient这个注解中:

@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class) 

三 Feign的优化

Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:

  • URLConnection:默认实现,不支持连接池

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

因此提高Feign的性能主要手段就是使用连接池代替默认的URLConnection。

这里使用HttpClient

  1. 引入依赖

    在order-service的pom文件中引入Apache的HttpClient依赖:

    <!--httpClient的依赖 -->
    <dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId><version>10.10.1</version>
    </dependency>
    
  2. 配置连接池

在order-service的application.yml中添加配置:

feign:client:config:default: # default全局的配置loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息httpclient:enabled: true # 开启feign对HttpClient的支持max-connections: 200 # 最大的连接数max-connections-per-route: 50 # 每个路径的最大连接数

总结,Feign的优化:

1.日志级别尽量用basic

2.使用HttpClient或OKHttp代替URLConnection

① 引入feign-httpClient依赖

② 配置文件开启httpClient功能,设置连接池参数


下面的是基于所做项目的描述,所以如果学习Feign到这里就够到,如果想要知道具体的实战应用,可以继续往下看.


四 (重要)Feign在开发中的使用方式

所谓最近实践,就是使用过程中总结的经验,最好的一种使用方式。

通过观察可以发现,Feign的客户端与服务提供者的controller代码非常相似:

// Feign的客户端
@FeignClient("user-service")  // value为对应的服务名
public interface UserClient {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);
}// 服务提供者的controller代码
@GetMapping("/user/{id}")
public User queryById(@PathVariable("id") Long id) {return userService.queryById(id);
}

那么 有没有一种办法简化这种重复的代码编写呢?

方式一 继承的方式(不推荐)

一样的代码可以通过继承来共享:

1)定义一个API接口,利用定义方法,并基于SpringMVC注解做声明。

2)Feign客户端和Controller都集成改接口

在这里插入图片描述

优点:

  • 简单
  • 实现了代码共享

缺点:

  • 服务提供方、服务消费方紧耦合
  • 参数列表中的注解映射并不会继承,因此Controller中必须再次声明方法、参数列表、注解

方式二 抽取方式

将Feign的Client抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用。

例如,将UserClient、User、Feign的默认配置都抽取到一个feign-api包中,所有微服务引用该依赖包,即可直接使用。

在这里插入图片描述

1)抽取

创建一个feign-api模块,

导入依赖

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

然后,将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中

在这里插入图片描述

2) 在order-service中使用feign-api

首先,删除order-service中的UserClient、User、DefaultFeignConfiguration等类或接口。

在order-service的pom文件中中引入feign-api的依赖:

<!-- 导入刚才自己创建的feign-api gav坐标 -->
<dependency><groupId>cn.itcast.demo</groupId><artifactId>feign-api</artifactId><version>1.0</version>
</dependency>

此时重启服务会发现

在这里插入图片描述

这是因为UserClient现在在cn.itcast.feign.clients包下,

而order-service的@EnableFeignClients注解是在cn.itcast.order包下,不在同一个包,无法扫描到UserClient。

解决扫描包问题

方式一:

指定Feign应该扫描的包:

@EnableFeignClients(basePackages = "cn.itcast.feign.clients")

方式二(推荐):

指定需要加载的Client接口:

@EnableFeignClients(clients = {UserClient.class})

相关文章:

Feign组件的使用及开发中使用方式

在微服务的服务集群中服务与服务之间需要调用暴露的服务.那么就需要在服务内部发送http请求&#xff0c; 我们可以使用较为老的HttpClient实现&#xff0c;也可以使用SpringCloud提供的RestTemplate类调用对应的方法来发送对应的请求。 说明&#xff1a; 现在有两个微服务一个是…...

html css 面试题

1. 如何理解HTML语义化 1&#xff0c;可读性&#xff0c;易读性 2&#xff0c;seo搜索引擎更容易读懂 2&#xff0c;哪些是块元素&#xff0c;哪些是内联元素 1&#xff1a;div&#xff0c;h1&#xff0c;table&#xff0c;ul&#xff0c;p 2&#xff1a;span&#xff0c; img…...

LeetCode_双指针_中等_24.两两交换链表中的节点

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&a…...

【openGauss实战11】性能报告WDR深度解读

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…...

Vue3实现打字机效果

typeit 介绍 typeit是一款轻量级打字机特效插件。该打印机特效可以设置打字速度&#xff0c;是否显示光标&#xff0c;是否换行和延迟时间等属性&#xff0c;它可以打印单行文本和多行文本&#xff0c;并具有可缩放、响应式等特点。官方文档 安装 # npm npm install typeit # …...

maven无法依赖spring-cloud-stater-zipkin如何解决?

当 Maven 无法依赖 spring-cloud-starter-zipkin 时&#xff0c;您可以尝试以下方法解决&#xff1a; 确保拼写正确&#xff1a;请检查项目中的 pom.xml 文件&#xff0c;确保依赖的拼写正确。正确的依赖名称应为&#xff1a;spring-cloud-starter-zipkin。添加 Spring Cloud …...

实战踩坑---MFC---CreateEvent

使用事件CreateEvent注意事项 HANDLECreateEvent( LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全属性 BOOLbManualReset,// 复位方式 BOOLbInitialState,// 初始状态 LPCTSTRlpName // 对象名称 );[1] 参数 lpEventAttributes[输入] 一个指向SECURITY_ATTRIBUTES结构…...

JavaWeb学习------jQuery

JavaWeb学习------jQuery jQuery函数库下载 jQuery函数库下载官网&#xff1a;Download jQuery | jQuery配套资料&#xff0c;免费下载 链接&#xff1a;https://pan.baidu.com/s/1aXBfItEYG4uM53u6PUEMTg 提取码&#xff1a;6c9i 然后下载&#xff1f; 来到官网&#xf…...

米哈游测开岗 【一面总结】

目录 1.黑盒测试与白盒测试的区别 2.测试一个下单功能 3.get与post的区别 4.一次get请求产生几个数据包 5.常用的linux命令 6.进程与线程的区别 7.数据库查询如何去重 8.MySql怎么连接两张表&#xff0c;有什么区别 9.说说索引 10.cookie 和 session 的区别 (会话管…...

微服务 Spring Boot 整合Redis 实现优惠卷秒杀 一人一单

文章目录 一、什么是全局唯一ID ⛅全局唯一ID ⚡Redis实现全局唯一ID 二、环境准备 三、实现秒杀下单 四、库存超卖问题 ⏳问题分析 ⌚ 乐观锁解决库存超卖 ✅Jmeter 测试 五、优惠卷秒杀 实现一人一单 ⛵小结 一、什么是全局唯一ID ⛅全局唯一ID 在分布式系统中,经常需要使用…...

构建OVS网络

构建OVS网络 1. 配置虚拟机环境 &#xff08;1&#xff09;配置虚拟机交换机 1 创建一个名为br-xd的虚拟交换机。 # ovs-vsctl add-br br-xd 2 查询虚拟交换机。 # ovs-vsctl show 5a1cd870-fc31-4820-a7f4-b75c19450582 Bridge br-xd Port br-xd …...

【Python】万能之王 Lambda 函数详解

Python 提供了非常多的库和内置函数。有不同的方法可以执行相同的任务&#xff0c;而在 Python 中&#xff0c;有个万能之王函数&#xff1a;lambda 函数&#xff0c;它可以以不同的方式在任何地方使用。今天云朵君将和大家一起研究下这个万能之王&#xff01; Lambda 函数简介…...

手把手教你怎么搭建自己的AI数字人直播间?帮你24小时不间断直播卖货

在搭建AI数字人直播间之前&#xff0c;您需要了解数字人技术。 一、什么是AI数字人、数字人直播间&#xff1f; 数字人是一种由人工智能技术构建的虚拟人物&#xff0c;其外貌、行为、语言等特征与真实人物相似&#xff0c;可以与人进行互动。数字人可以通过语音合成、人脸识…...

MySQL性能监控全掌握,快来get关键指标及采集方法!

数据库中间件监控实战&#xff0c;MySQL中哪些指标比较关键以及如何采集这些指标了。帮助提早发现问题&#xff0c;提升数据库可用性。 1 整体思路 监控哪类指标&#xff1f; 如何采集数据&#xff1f; 第10讲监控方法论如何落地&#xff1f; 这些就可以在MySQL中应用起来。…...

sed进阶之保留空间和排除命令

shell脚本编程系列 保留空间 模式空间&#xff08;pattern space&#xff09;是一块活跃的缓冲区&#xff0c;在sed编辑器执行命令时保存着待检查的文本&#xff0c;但它并不是sed编辑器保存文本的唯一空间。sed编辑器还有另一块称作保留空间&#xff08;hold space&#xff0…...

21安徽练习

题目分为4部分 APK 集群 流量 exe 我尽量都做一下&#xff0c;逆向不是很会&#xff0c;就当提升自己。 [填空题]请获取app安装包的SHA256校验值&#xff08;格式&#xff1a;不区分大小写&#xff09;&#xff08;10分&#xff09; e15095d49efdccb0ca9b2ee125e4d8136cac5…...

【VAR | 时间序列】应用VAR模型时的15个注意点

一、前言 向量自回归&#xff08;VAR,Vector Auto regression&#xff09;常用于预测相互联系的时间序列系统以及分析随机扰动对变量系统的动态影响。 VAR方法通过把系统中每一个内生变量,作为系统中所有内生变量的滞后值的函数来构造模型&#xff0c;从而回避了结构化模型的…...

校招在线测评题目汇总

图形找规律题 https://blog.csdn.net/mxj1428295019/article/details/129627461https://blog.csdn.net/Yujian2563/article/details/124266574?spm1001.2101.3001.6650.2&utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-124266574-blo…...

『python爬虫』05. requests模块入门(保姆级图文)

目录 安装requests1. 抓取搜狗搜索内容 requests.get2. 抓取百度翻译数据 requests.post3. 豆瓣电影喜剧榜首爬取4. 关于请求头和关闭request连接总结 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 安装requests …...

WPF超好用的框架Prism入门使用,上位机赶紧学起来!

Prism简介 WPF框架Prism是一种用于开发模块化、可重用和可测试的WPF应用程序的框架。它提供了一种简单而强大的方式来管理复杂应用程序的代码和构建高度可扩展的应用程序。 如何学习Prism框架 如果您想使用Prism框架来开发WPF应用程序&#xff0c;需要学习以下几个方面&…...

YOLOv5 COCO数据集 实战训练全流程解析 | 【从零到一】

1. 环境准备&#xff1a;从零搭建YOLOv5训练环境 第一次接触YOLOv5时&#xff0c;我最头疼的就是环境配置。记得当时为了一个CUDA版本问题折腾了整整两天&#xff0c;现在回想起来其实只要按步骤来就能避免90%的坑。下面是我总结的最稳环境搭建方案&#xff1a; 首先确保你的机…...

解码Voron 2.4:开源高速CoreXY 3D打印机的架构哲学与工程实践

解码Voron 2.4&#xff1a;开源高速CoreXY 3D打印机的架构哲学与工程实践 【免费下载链接】Voron-2 Voron 2 CoreXY 3D Printer design 项目地址: https://gitcode.com/gh_mirrors/vo/Voron-2 Voron 2.4作为开源3D打印机领域的标杆产品&#xff0c;代表了CoreXY架构在高…...

HC32F4A0 ADC+DMA实战:8通道模拟量采集,从时钟配置到数据搬运的保姆级避坑指南

HC32F4A0 ADCDMA实战&#xff1a;8通道模拟量采集全流程精解与典型问题排查 在工业控制、智能家居和物联网设备开发中&#xff0c;多通道模拟信号采集是嵌入式系统的基础功能。HC32F4A0作为华大半导体推出的高性能MCU&#xff0c;其ADC模块配合DMA控制器可实现高效的数据采集方…...

CherryPy与数据库集成:SQLAlchemy和ORM模式详解

CherryPy与数据库集成&#xff1a;SQLAlchemy和ORM模式详解 【免费下载链接】cherrypy CherryPy is a pythonic, object-oriented HTTP framework. https://cherrypy.dev 项目地址: https://gitcode.com/gh_mirrors/ch/cherrypy CherryPy是一个Python风格的面向对象HTTP…...

如果写好AI提示词:这份 Prompt 调试速查表帮你事半功倍

有句话说得好&#xff1a;"好的工程师和差的工程师的区别&#xff0c;不在于他们多聪明&#xff0c;而在于他们有没有一份好的排障清单。"这句话对 Prompt 工程也完全适用。最近三个月&#xff0c;我在 Claude 社区的 Discord 里帮人调试 Prompt。最常见的情况是什么…...

别再只会用t检验了!用Python的statsmodels库做单因素方差分析,5分钟搞定A/B测试结果解读

用Python实现单因素方差分析&#xff1a;A/B测试中的多组比较实战指南 当产品经理同时测试三种新按钮颜色对转化率的影响时&#xff0c;连续做了三次t检验对比各组差异——这个在互联网公司会议室里反复上演的场景&#xff0c;实际上犯了一个统计学上的典型错误。就像用三把尺…...

手把手教你用Arduino+ELM327读取OBD-II数据(附代码和常见故障码解析)

用Arduino与ELM327打造智能车载数据监控系统 在创客圈子里&#xff0c;车辆数据监控一直是个既实用又有趣的领域。想象一下&#xff0c;用不到200元的硬件成本&#xff0c;就能实时读取发动机转速、油耗数据甚至诊断车辆潜在故障——这正是Arduino与ELM327组合带来的可能性。不…...

1、Chrome Elements面板:从入门到精通的网页调试实战指南

1. Chrome Elements面板&#xff1a;你的网页调试瑞士军刀 第一次打开Chrome开发者工具时&#xff0c;那个标着"Elements"的标签页看起来就像是一堆杂乱无章的HTML代码。但当我真正开始理解它的功能后&#xff0c;它迅速成为了我每天使用最频繁的开发工具。Elements面…...

AI智能体视觉(TVA)实战教程(1)

重磅预告&#xff1a;本专栏将独家连载新书《AI视觉技术&#xff1a;从入门到进阶》精华内容。本书是《AI视觉技术&#xff1a;从进阶到专家》的权威前导篇&#xff0c;特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“AI教…...

ACL 2026 | 未见伪造也能识别:「证链侦探」破解“泛化失灵”困局

AI 生成图像、AI 编造文本、图文协同伪造……今天的多模态虚假内容&#xff0c;已经越来越复杂。面对训练中没见过的新新闻域、新操纵方式、新组合套路&#xff0c;很多现有鉴伪模型往往就开始“掉链子”。问题的关键不只是伪造更多了&#xff0c;而是模型学到的东西太像“背答…...