Spring Cloud — 深入了解Eureka、Ribbon及Feign

embedded/2025/2/22 20:48:20/

 Eureka 负责服务注册与发现;Ribbon负责负载均衡;Feign简化了Web服务客户端调用方式。这三个组件可以协同工作,共同构建稳定、高效的微服务架构。

1 Eureka

分布式系统的CAP定理:

一致性(Consistency):同一个数据在集群中的所有节点,同一时刻都是同样的值。

可用性(Availability):集群中一部分节点故障后,集群整体还能处理客户端的请求。即每个请求都能收到一个(无论成功或失败)响应,且不会出现超时等情况。

分区容忍性(Partition tolerance):系统可用容忍消息的丢失或节点间通信的延迟。即分布式系统出现网络分区(由于网络故障导致系统中一部分节点无法与其他节点通信,从而形成孤立的分区)时,系统能否继续提供服务并保持数据一致性的能力。

在任何分布式系统中,不可能同时满足这三项,最多同时满足两项。

微服务的治理,核心是服务的注册和发现,针对同一服务,即使注册中心的不同节点保存的服务提供者信息不尽相同,也不会造成灾难性后果。对于消费者来说,能消费服务才是最重要的。即对于微服务的治理,遵循的是AP。

1.1 实现原理

图 服务提供者的服务生命周期

1.1.1 服务注册 Register

在服务提供者配置文件中将eureka.client.register-with-eureka的属性配置为true时,当服务提供者启动时,会调用Eureka所提供的服务注册相关方法,向Eureka服务器注册自己的信息。Eureka服务器会维护一个已注册的服务列表。

Eureka的AbstractInstanceRegistry类的ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry 字段存储了已注册的服务列表,

key 是服务的应用名称。value包含了服务实例的详细信息。

当服务实例状态发生变化时(比如不可用),服务提供者会向Eureka服务器更新自己的服务状态,同时会向其他Eureka服务器节点做状态同步。

1.1.2 服务续约 Renew

当将服务成功注册到Eureka服务器后,客户端会默认以30s(客户端配置属性eureka.instance.lease-renewal-interval-in-seconds)的频率向Eureka服务器发生一次心跳(即执行服务续约操作),来避免自己的注册信息被Eureka服务器剔除。

Eureka如果在90s内(客户端配置属性eureka.instance.lease-expiration-duration-in-seconds)没有收到客户端的心跳,则会将该服务实例从所维护的服务注册表中剔除,以禁止流向该实例的流量。

不过,当Eureka服务器处于自护保护模式时,不会清除服务实例信息。

1.1.3 获取服务

消费者端(fetch-registry属性配置为true)启动时会从Eureka服务器中获取注册表信息,并将其缓存在本地。并定期(默认30s)从Eureka服务器进行同步。

1.1.4 服务下线与剔除

当服务实例关闭时,会先向Eureka服务器发送服务下线请求,Eureka收到请求后,会将该服务实例信息从实例注册表中删除。

1.2 Eureka自我保护模式

图 处于自我保护模式下的Eureka服务

当Eureka处于自我保护模式时,会出现上面的红字提示,大概意思是:Eureka可能错误地报告服务实例为在线状态,而实际上它们可能并不在线。

这个问题是由于续租(Renewals)的数量低于阈值,导致服务实例没有被正确地标记为过期,从而可能影响到系统的稳定性和可用性。当Eureka每分钟收到心跳续租的数量恢复到阈值以上时,就会退出自我保护模式。

1.3 Eureka 高可用集群

Eureka服务器采用的是P2P(Peer to Peer)对等通信,是一种去中心化的结构。每个节点都是对等的。为了让Eureka服务高可用,必须让Eureka服务器之间能互相复制、同步所注册服务的实例信息。

图 Eureka集群注册模式

Eureka服务器配置文件中,register-with-eureka及fetch-registry属性都需要配置为true。eureka.client.service-url.defaultZone属性需要配置其他两个Eureka的服务器地址。

2 Bibbon

图 负载均衡方案核心部分

2.1 Ribbon 组件

Ribbon在实现负载均衡主要使用了6个组件。

2.1.1 服务器列表 ServerList

客户端负载均衡所使用的各服务实例列表,Ribbon支持下面3种方式:

  1. 静态服务器列表:通过BaseLoadBalancer的setServersList()方法进行设置。
  2. 基于配置的服务器列表:配置文件中通过<服务名称>.ribbon.listOfServers 属性进行配置。
  3. 基于服务发现的服务器列表:当在应用中同时使用Ribbon和Eureka时,默认会使用这种方式。当客户端启动时Ribbon会从Eureka服务器中获取所有注册服务的列表数据,并保持同步。

2.1.2 服务器列表过滤器 ServerListFilter

使用动态服务器列表时,过滤器会对原始服务列表使用一定的策略进行过滤。

ZoneAffinityServerList

Filter

仅返回与本身所处区域一致的服务提供者实例列表。

ServerListSubset

Filter

继承了ZoneAffinityServerListFilter,经过区域过滤后,仅返回一个固定大小的服务列表。

ZonePreferenceServerList

Filter

通过配置或Eureka所属区域来过滤出同区域的服务实例列表。使用Spring Cloud整合Eureka和Ribbon时会默认使用该过滤器。

图 具体的服务器列表过滤器

2.1.3 服务实例存活探测 IPing

就像ping指令一样,用来监测一个微服务实例是否有响应。如果监测到某服务实例不再可用则会从列表中及时剔除。

2.1.4 负载均衡策略 IRule

负责选择一个最终服务实例地址作为负载均衡处理结果。Ribbon提供的选择策略有轮询、根据响应时间加权、断路由等。

2.1.5 负载均衡器 ILoadBalancer

负载均衡的具体实现。

DynamicServerList

LoadBalancer

运行期间对服务实例动态更新和过滤。

ZoneAware

LoadBalancer

基础上面的类。并增加防止跨区域访问的功能。

NoOp

LoadBalancer

不执行实际的负载均衡操作。不会将请求分发到不同的服务实例上。

表 ILoadBalancer接口的具体实现类

2.1.6 服务调用器 RestClient

负载均衡后,Ribbon向服务提供者发起REST请求的工具。

2.2 负载均衡策略

Ribbon提供了以下几种负载均衡策略:

1. 轮询策略,RoundRobinRule。轮询方式选择服务实例。即每次调度执行i=(count + 1) mod n,来选出第i台服务器实例。count为执行请求的计数次数。

2. 随机选择,RandomRule。随机从可用的服务实例列表中选择一个。

3. 带有加权的轮询策略,WeightedResponseTimeRule。对各个服务实例响应时间进行加权处理,然后再采用轮询的方式。

Ribbon会对每个服务实例的响应时间进行统计,根据记录的时间计算每个服务实例的权重,最后根据每个实例的权重进行概率选择。

4 .可用过滤策略,AvailabilityFilteringRule。先过滤出有故障或并发请求大于阈值的部分服务实例,然后再以线性轮询的方式。

5 .区域感知策略,ZoneAvoidanceRule。先使用主过滤条件(区域负载器,选择最优区域)来进行过滤,然后使用次过滤条件进行过滤。最后对满足条件的服务实例使用轮询策略。

3 Feigh

Feign 提供了一个简洁的接口来定义和调用远程服务。

3.1 参数绑定

在Spring MVC 中注解会以参数每次作为默认值,但Feign不会,必须声明。

@RequestMapping(value = "/user/info",method = RequestMethod.GET)
String info(@RequestParam String name);

例如上面的代码,在Spring MVC中能获取到name这个参数值,但在Feign中不会,必须写为 @RequestParam(“name”) String name。

Feign 支持Spring MVC的注解,Spring MVC中常用的注解有以下几种:

@RequestParam: 绑定单个请求参数值。

@PathVariable:绑定URI模板变量值。

@RequestHeader:绑定请求头数据。

@RequestBody:绑定请求体数据。


http://www.ppmy.cn/embedded/164095.html

相关文章

区块链技术:构建区块链生态的核心要素

区块链技术&#xff0c;作为一种去中心化的分布式账本技术&#xff0c;近年来在金融、供应链、医疗、物联网等多个领域展现出巨大的应用潜力。其核心要素共同构成了这一革命性技术的基础&#xff0c;推动了区块链生态的持续发展。本文将深入探讨构建区块链生态的核心要素&#…

vscode的一些实用操作

1. 焦点切换(比如主要用到使用快捷键在编辑区和终端区进行切换操作) 2. 跳转行号 使用ctrl g,然后输入指定的文件内容&#xff0c;即可跳转到相应位置。 使用ctrl p,然后输入指定的行号&#xff0c;回车即可跳转到相应行号位置。 3. 进入函数内部 使用ctrl F12

Java 语言线程池的原理结构

在 Java 中&#xff0c;线程池是一种用于管理线程的机制&#xff0c;它可以有效地复用线程&#xff0c;减少线程创建和销毁带来的开销&#xff0c;提高系统的性能和稳定性。下面详细介绍 Java 语言线程池的原理结构。 核心类和接口 Java 线程池的核心类和接口主要位于 java.u…

ios UICollectionView使用

UICollectionView列表视图和UITableView用法类似&#xff0c;直接给出代码 // // myUICollectionViewTestController.m // iosstudy2024 // // Created by figo on 2025/1/21. //#import "UICollectionViewTestController.h"interface UICollectionViewTestContr…

阿里云虚机的远程桌面登录提示帐户被锁定了

提示由于安全原因&#xff0c;帐户被锁定。 阿里云虚机ECS的远程桌面登录提示帐户被锁定了&#xff0c;只能登录阿里云处理 阿里云-计算&#xff0c;为了无法计算的价值 需选择通过VNC连接 然后计算机管理&#xff0c;解除帐户锁定即可。

DeepSeek R1生成图片总结2(虽然本身是不能直接生成图片,但是可以想办法利用别的工具一起实现)

DeepSeek官网 目前阶段&#xff0c;DeepSeek R1是不能直接生成图片的&#xff0c;但可以通过优化文本后转换为SVG或HTML代码&#xff0c;再保存为图片。另外&#xff0c;Janus-Pro是DeepSeek的多模态模型&#xff0c;支持文生图&#xff0c;但需要本地部署或者使用第三方工具。…

phpmyadmin 文件包含(CVE-2014-8959)

目录 漏洞描述 1.攻击机配置go环境&#xff1a; 2.点击“数据库”抓包token值 3.拿到flag&#xff1a; 漏洞描述 phpMyAdmin是一套开源的、基于Web的MySQL数据库管理工具。其index.php中存在一处文件包含逻辑&#xff0c;通过二次编码即可绕过检查&#xff0c;造成远程文件…

css里flex+margin布局

css里flexmargin布局 居中两端排列依次排列 在flexmargin的布局中&#xff0c;margin设置auto会自动将元素剩余的空间用margin填满 居中 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>居中</tit…