快速理解微服务中Fegin的概念

news2024/11/29 17:10:16

一.由来

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 {
    @Bean
    public 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 {
    @Bean
    public RequestInterceptor requestInterceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
                // 添加认证信息到请求头中
                template.header("Authorization", "Bearer " + getToken());
            }
        };
    }

    private String getToken() {
        return "token";
    }
}

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

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

相关文章

【Git】Git 完全指南:从入门到精通

Git 完全指南:从入门到精通 Git 是现代软件开发中最重要的版本控制工具之一,它帮助开发者高效地管理项目,支持分布式协作和版本控制。无论是个人项目还是团队开发,Git 都能提供强大的功能来跟踪、管理代码变更,并保障…

Spring Web MVC(详解中)

文章目录 Spring MVC(中)RESTFul风格设计RESTFul风格概述RESTFul风格特点RESTFul风格设计规范RESTFul风格好处RESTFul风格实战需求分析RESTFul风格接口设计后台接口实现 基于RESTFul风格练习(前后端分离模式)案例功能和接口分析功…

什么是GAN?

一、基本概念 生成对抗网络(Generative Adversarial Network,GAN)是一种由两个神经网络共同组成深度学习模型:生成器(Generator)和判别器(Discriminator)。这两个网络通过对抗的方式…

Spring |(八)AOP配置管理

文章目录 📚AOP切点表达式🐇语法格式🐇通配符 📚AOP通知类型🐇环境准备🐇通知类型的使用 📚AOP通知获取数据🐇环境准备🐇获取参数🐇获取返回值🐇获…

Flink 从入门到实战

Flink中的批和流 批处理的特点是有界、持久、大量,非常适合需要访问全部记录才能完成的计算工作,一般用于离线统计。 流处理的特点是无界、实时, 无需针对整个数据集执行操作,而是对通过系统 传输的每个数据项执行操作,一般用于实…

Ubuntu20.04运行LARVIO

文章目录 1.运行 Toyish 示例程序2.运行 ROS Nodelet参考 1.运行 Toyish 示例程序 LARVIO 提供了一个简化的toyish示例程序,适合快速验证和测试。 编译项目 进入 build 文件夹并通过 CMake 编译项目: mkdir build cd build cmake -D CMAKE_BUILD_TYPER…

小程序-基于java+SpringBoot+Vue的戏曲文化苑小程序设计与实现

项目运行 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

mybatis plus如何使用mybatis xml拼接sql

在 MyBatis Plus 中,如果你想使用 MyBatis 的 XML 文件来拼接 SQL,可以结合使用 MyBatis 和 MyBatis Plus 的功能。MyBatis Plus 是一个增强 MyBatis 的工具,它提供了很多便捷的操作,但有时你可能需要使用 XML 文件来定义更复杂的…

【uniapp】轮播图

前言 Uniapp的swiper组件是一个滑块视图容器组件&#xff0c;可以在其中放置多个轮播图或滑动卡片。它是基于微信小程序的swiper组件进行封装&#xff0c;可以在不同的平台上使用&#xff0c;如微信小程序、H5、App等。 效果图 前端代码 swiper组件 <template><vi…

Python爬虫爬取数据报错

报错&#xff1a; Error fetching the URL: (Connection aborted., ConnectionResetError(10054, 远程主机强迫关闭了一个现有的连接。, None, 10054, None)) 报错原因&#xff1a; 目标服务器限制&#xff1a; 目标网站可能已经检测到你的请求来自自动化工具&#xff08;如爬虫…

人工智能与传统控制系统的融合发展

在这个科技快速迭代的时代&#xff0c;人工智能技术正以前所未有的速度改变着我们的生活。在控制系统领域&#xff0c;AI技术的引入为传统控制带来了新的发展机遇和挑战。然而&#xff0c;这并不意味着传统控制将被完全取代&#xff0c;相反&#xff0c;AI与传统控制的深度融合…

shell综合

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

什么是串联谐振

比如有一个由电阻、电容和电感的串联电路中&#xff0c;存在一个频率能使这个电路的电流最大&#xff0c;这个现象就叫谐振。 那么这个频率是多少呢&#xff1f; 交流电频率与电路固有频率一致时&#xff0c;它就能发生谐振&#xff0c;此时这个电路的电流是最大的 这个固有频…

韦东山stm32hal库--定时器喂狗模型按键消抖原理+实操详细步骤

一.定时器按键消抖的原理: 按键消抖的原因: 当我们按下按键的后, 端口从高电平变成低电平, 理想的情况是, 按下, 只发生一次中断, 中断程序只记录一个数据. 但是我们使用的是金属弹片, 实际的情况就是如上图所示, 可能会发生多次中断,难道我们要记录3/4次数据吗? 答:按键按下…

雨云服务器搭建docker且用docker部署kali服务器教程

雨云 - 新一代云服务提供商 介绍 大家好今天教大家如何使用雨云的服务器安装docker并且用docker搭建kali服务器&#xff0c;实现大家做黑客的梦。 性价比比较高的云服务器提供参考&#xff1a;雨云 - 新一代云服务提供商 优惠码&#xff1a;MzkxODI4 什么是kali Kali L…

SQL进阶——JOIN操作详解

在数据库设计中&#xff0c;数据通常存储在多个表中。为了从这些表中获取相关的信息&#xff0c;我们需要使用JOIN操作。JOIN操作允许我们通过某种关系&#xff08;如相同的列&#xff09;将多张表的数据结合起来。它是SQL中非常重要的操作&#xff0c;广泛应用于实际开发中。本…

分析JHTDB数据库的Channel5200数据集的数据(SciServer服务器)

代码来自https://github.com/idies/pyJHTDB/blob/master/examples/channel.ipynb %matplotlib inline import numpy as np import math import random import pyJHTDB import matplotlib.pyplot as plt import time as ttN 3 T pyJHTDB.dbinfo.channel5200[time][-1] time …

数据分析:彩票中奖号码分析与预测

预测双色球彩票的中奖号码是一个典型的随机事件&#xff0c;因为每个号码的出现概率是独立的&#xff0c;且历史数据并不能直接用于预测未来的开奖结果。然而&#xff0c;我们可以通过统计分析来了解号码的分布规律&#xff0c;从而提供一些可能的参考。 样例数据【点击下载】…

详细分析 npm run build 基本知识 | 不同环境不同命令

目录 前言1. 基本知识2. 构建逻辑 前言 关于部署服务器的知识推荐阅读&#xff1a;npm run build部署到云服务器中的Nginx&#xff08;图文配置&#xff09; 1. 基本知识 npm run 是 npm 的一个命令&#xff0c;用于运行 package.json 中定义的脚本&#xff0c;可以通过 “s…

Jpype调用jar包

需求描述 ​   公司要求使用python对接口做自动化测试&#xff0c;接口的实现是Java&#xff0c;部分接口需要做加解密&#xff0c;因此需要使用python来调用jar包来将明文加密成密文&#xff0c;然后通过http请求访问接口进行测试。 如何实现 1.安装Jpype ​   首先我…