快速理解微服务中Fegin的概念
一.由来
1.在传统的架构里面,我们是通过使用RestTemplate来访问其他的服务,但是这种方式就存在了一个很大的缺陷,也就是被调用方如果发生了服务的迁移(IP和端口发生了变化),那么调用方也需要同步的在代码里面进行修改,然后重启服务;
2.这种方法在微服务新起以后,它的弊端就被无线放大,因此这个方式就逐渐的演变,然后形成了注册中心和配置中心,虽然我们使用注册中心解决服务发送迁移等等其他的一系列问题,但是最根本的服务之间的Http访问问题还是没有解决;
3.在两个服务之间,需要发生调用,它首先需要来到注册中心,在注册中心拿到相应的服务以后,再在本地进行负载,负载之后再发起远程调用,但是在微服务里面,服务的调用是非常的频繁,比如在一个方法里面可能出现多个服务的调用,那么同一个服务之间的调用就出现了代码的冗余。(我们以为最简单的为例:比如我们通过一个代码来都注册中心里面,拉取这个注册配置,然后再本地进行负载,负载之后再通过RestTemplate进行访问,也就是说一次简单的调用就需要写三行代码,如果是多个服务,就要编写更多的代码,这样就出现了代码的冗余)
因此,基于这种场景就引入了Fegin。
二.基本概念
1.Fegin是一个声明式的Web服务客户端,它简化了使用基于HTTP的远程服务开发;(相当于把我们上面说的三行代码进行了一个封装,当我们使用远程调用的时候,直接使用Fegin,然后Fegin的底层来帮我们实现这个调用的过程)
2.Fegin是在RestTemplate和Ribbon的基础上进一步封装,使用RestTemplate实现Http调用,使用Ribbon实现负载均衡,关系如图所示:

Feign的主要特点和功能包括:
1.声明式API:Feign允许开发者使用简单的注解来定义和描述对远程服务的访问,通过使用注解,开发者可以轻松地指定URL、HTTP方法、请求参数、请求头等信息,使得远程调用变得非常直观和易于理解。
@FeignClient(name = "example", url = "https://api.example.com")public interface ExampleService {@GetMapping("/endpoint")String getEndpointData();}
2.集成负载均衡:Feign集成了Ribbon负载均衡器,可以自动实现客户端的负载均衡,它可以根据服务名和可用实例进行动态路由,并分发请求到不同的服务实例上,提高系统的可用性和可伸缩性;(我们不需要来处理负载均衡了,由Fegin来帮我们集成了)
3.容错机制:Feign支持集成Hystrix容错框架,可以在调用远程服务时提供容错和断路器功能(防止雪崩),当远程服务不可用或响应时间过长时,Feign可以快速失败并返回预设的响应结果,避免对整个系统造成级联故障。
3.自定义错误处理:允许你配置自定义的错误处理策略,当远程服务返回错误时,能够进行定制化的处理:
@FeignClient(name = "user-service", configuration = CustomFeignConfiguration.class)
public interface UserClient {// 方法定义
}@Configuration
public class CustomFeignConfiguration {@Beanpublic ErrorDecoder errorDecoder() {return new MyCustomErrorDecoder(); // 自定义错误解码器}
}
注意:
在2019年,Netflix宣布停止对Feign的维护,为了替代 Feign ,Spring Cloud 社区推出了 OpenFeign,它继承了Feign的所有功能,并增加了对Spring MVC注解的支持,OpenFeign目前仍在维护中,特别是在Spring Cloud Finchley及以上版本中广泛使用。
其实,OpenFeign 和 Feign 在使用方式上非常相似,因为 OpenFeign 是 Feign 的社区版,并且在设计上保持了与 Feign 一致的 API 和功能,换句话说,OpenFeign 基本上是对 Feign 的延续和改进,尤其是在与 Spring Cloud 集成方面,所以,二者的使用方式差异并不大。
三.为什么Fegin第一次调用耗时很长?
主要原因是由于Ribbon的懒加载机制,当第一次调用发生时,Fegin会触发Ribbon的加载过程,包括从服务注册中心获取服务列表、建立连接池等操作,这个加载过程会增加首次调用的耗时。
解决方案:
ribbon:eager-load:enabled: true // 开启饥饿加载clients: service-1 // 服务名,多个以逗号隔开
可以在应用启动时预热Fegin客户端,自动触发一次无关紧要的调用,来提前加载Ribbon和其他相关组件,这个,就相当于提前进行了一次调用。
四.Fegin是怎么做负载均衡?
在Feign中,负载均衡是通过集成Ribbon来实现的。
Ribbon是Netfix开源的一个客户端负载均衡器,可以与Feign无缝集成,为Feign提供负载均衡的能力。
Ribbon在发起请求前,会从“服务中心”获取服务列表(清单),然后按照一定的负载均衡策略去发起请求,从而实现客户端的负载均衡。

Ribbon本身也维护着“服务提供者”清单的有效性,相当于是缓存了服务清单,只有当它发现“服务提供者”不可用,才会重新从“服务中心”获取有效的“服务提供者”清单来及时更新,并不是每一次调用都会进行拉取,这种方式也提高了整个系统的性能。
五.Fegin怎么实现认证传递?
首先先我们需要知道,为什么Fegin需要实现认证传递?先了解一下微服务的完调用链路:

1.通常用户在前端进行请求,请求就就会到达Nginx,然后Nginx就会进行转发,到达我们的Api网关层,在Api网关层就会通过一个过滤器来实现一个认证服务,然后校验通过的请求就会将相应的认证信息或者是用户信息存到请求头里面;
2.网关完成认证之后,就会将请求转发到一个具体的微服务,微服务中使用HandlenInterceptor拦截器来获取Api层传递过来的认证信息,使用过滤器和拦截器就打通了Api层和微服务层的一个认证信息的传递;
3.但是,其实大量的请求并不是直接通过网关层到达服务层,而是直接由微服务之间的调用产生,微服务都是通过了HandlenInterceptor拦截器来获取请求头里面的信息,而微服务之间的调用是通过了openFegin来进行处理的,而使用openFegin时并没有在请求头中添加相应的一个请求信息,所以被调用的微服务就没有办法直接使用拦截器获取到一个相应的认证信息,所以为了解决这个问题,就需要在openfegin调用的时候将相应的用户信息或认证信息存储到请求头里面,这样才能完成微服务之间的一个认证问题。
解决方案:
比较常见的一种做法就是使用拦截器传递认证信息,可以通过实现RequestInterceptor接口来定义拦截器,在拦截器里,把认证信息添加到请求头中,然后将其注册到Fegin的配置中。
@Configuration
public class FeignclientConfig {@Beanpublic RequestInterceptor requestInterceptor() {return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate template) {// 添加认证信息到请求头中template.header("Authorization", "Bearer " + getToken());}};}private String getToken() {return "token";}
}相关文章:
快速理解微服务中Fegin的概念
一.由来 1.在传统的架构里面,我们是通过使用RestTemplate来访问其他的服务,但是这种方式就存在了一个很大的缺陷,也就是被调用方如果发生了服务的迁移(IP和端口发生了变化),那么调用方也需要同步的在代码里面进行修改,…...
新增工作台模块,任务中心支持一键重跑,MeterSphere开源持续测试工具v3.5版本发布
2024年11月28日,MeterSphere开源持续测试工具正式发布v3.5版本。 在这一版本中,MeterSphere新增工作台模块,工作台可以统一汇总系统数据,提升测试数据的可视化程度并增强对数据的分析能力,为管理者提供测试工作的全局…...
快速搭建一个博客!!!“Halo框架深度优化:搭建你的个性化博客或网站”
目录 引言: 一. 首先服务器上去下载一个docker 1.可以参考官方地址: 2. 通过宝塔来一键安装!!! 3.也可以自己下载!!! 1.卸载旧版 2.配置Docker的yum库 3.安装Docker 4.启动和…...
009 STM32 HAL库介绍
STM32 HAL库(Hardware Abstraction Layer)是STMicroelectronics为STM32系列微控制器提供的一套硬件抽象层库,它旨在简化STM32的开发过程,提高代码的可移植性和可维护性。HAL库通过提供一组统一的API接口,使得开发者无需…...
【微服务】 Eureka和Ribbon
一、Eureka 服务调用出现的问题:在远程调用另一个服务时,我们采用的解决办法是发送一次http请求,每次环境的变更会产生新的地址,所以采用硬编码会出现很多麻烦,并且为了应对并发问题,采用分布式部署&#…...
6.算法移植第六篇 YOLOV5/rknn生成可执行文件部署在RK3568上
接上一篇文章best-sim.rknn模型生成好后,我们要将其转换成可执行文件运行在RK3568上,这一步需要在rknpu上进行,在强调一遍!!rknpu的作用是可以直接生成在开发板上运行的程序 退出上一步的docker环境 exit1.复制best-…...
element的el-table表格标题用css自定义是否必填,用添加伪类的方式标红色*
element的el-table表格标题用css自定义是否必填添加伪类红色 * 效果图如下👇 el-table组件的html部分 css部分 /deep/.el-table__header-wrapper{.el-table__header{.has-gutter tr .el-table__cell:nth-of-type(3) .cell:before{content: *;color:red}.has-gutte…...
数据仓库: 8- 数据仓库性能优化
CSDN 目录展示 目录 8- 数据仓库性能优化8.1 查询优化8.1.1 索引优化8.1.2 分区和分桶8.1.3 使用缓存8.1.4 查询简化与重写8.1.5 聚合优化8.1.6 并行化和分布式计算8.1.7 基于列存储的优化8.1.8 表的分区和数据清洗8.1.9 查询提示 (Hints)8.1.10 自动调优工具 8.2 索引设计8.2…...
可编程网络在分布式深度学习通信瓶颈控制中的应用与未来展望
目录 可编程网络在分布式深度学习通信瓶颈控制中的应用与未来展望 可编程网络在分布式深度学习通信瓶颈控制中的应用与未来展望 在分布式深度学习领域,随着模型规模的不断扩大,训练过程中的通信开销已成为制约性能提升的关键因素。传统的分布式训练方法面临高通信延迟和带宽…...
【论文笔记】Tool Learning with Foundation Models 论文笔记
Tool Learning with Foundation Models 论文笔记 文章目录 Tool Learning with Foundation Models 论文笔记摘要背景:工作: 引言工具学习的发展本文工作(大纲&目录) 背景2.1 工具使用的认知起源2.2 工具分类:用户界…...
Springfox迁移到 Springdoc OpenAPI 3
将项目从 Springfox 迁移到 Springdoc OpenAPI 3 时,主要的工作是将原先使用的 Springfox 注解替换为 Springdoc OpenAPI 3 中的对应注解。虽然 Springdoc OpenAPI 3 基于 OpenAPI 3 规范,并且有一些不同的命名方式和设计理念,但大部分注解的…...
DIY-Tomcat part 3 实现对动态资源的请求
实现ServletRequest package connector;import javax.servlet.RequestDispatcher; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i…...
3.10 内核 BUG_ON() at xfs_vm_writepage() -> page_buffers()
目录 前言 问题分析 page buffers创建 page buffers丢失 Write-Protect Dirty Page w/o Buffers 问题解决 前言 这个问题发生在3.10.0-514.el7上,并且在RHEL的知识库中快速找到了对应的案例以及解决方案,但是,理解问题如何发生和解决…...
CrystalDiskInfo:硬盘健康监测工具简介和下载
原论坛给你更好的阅读体验:CrystalDiskInfo:硬盘健康监测工具简介和下载 | 波波论坛 引言 在日常使用电脑时,硬盘的健康状态对于系统的稳定性和数据的安全性至关重要。硬盘出现故障可能会导致数据丢失,严重时甚至会使整个系统无…...
Flink cdc同步增量数据timestamp字段相差八小时(分析|解决)不是粘贴复制的!
问题 我使用flink cdc同步mysql到mysql遇到了timestamp字段缺少八小时的问题。很少无语,flink ,cdc,debezium时区都设置了,没有任何效果! 分析 问题出现在mysql binlog身上!!! 因为默认mysql会使用UTC来…...
【docker】9. 镜像操作与实战
镜像操作案例 查找镜像 docker search busybox下载镜像 docker pull busybox:1.36.0查看镜像及列表存储位置 rootLAPTOP-H2EI4I6A:~# docker images busybox REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest 517b897a6a83 2 months a…...
js-显示转换(强制转换)与隐式转换,==与===区别
1.显示转换(强制转换)与隐式转换 1.1显示转换 常见的JavaScript强制转换示例。 (1) 一元加号、一元减号- 值是布尔值,true将被转换为1,false将被转换为0。 let a "123"; let b a; // b的值为123,类型为Nu…...
【通俗理解】步长和学习率在神经网络中是一回事吗?
【通俗理解】步长和学习率在神经网络中是一回事吗? 【核心结论】 步长(Step Size)和学习率(Learning Rate, LR)在神经网络中并不是同一个概念,但它们都关乎模型训练过程中的参数更新。 【通俗解释&#x…...
【PTA】【数据库】【SQL命令】编程题2
数据库SQL命令测试题2 测试题目录 10-1 查询“李琳”老师所授课程的课程名称10-2 查询成绩比所有课程的平均成绩高的学生的学号及成绩10-3 创建带表达式的视图StuView10-4 从视图PerView中查询数据10-5 查询工资高于在“HR”部门工作的所有员工的工资的员工信息10-6 查询选修的…...
Spring Boot林业产品推荐系统:用户指南
摘 要 网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代,所以对于信息的宣传和管理就很关键。因此林业产品销售信…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
