2.Netflix Eureka(服务注册/发现)基本介绍

目录


Spring Cloud专栏目录(点击进入…)



Netflix Eureka(服务注册/发现)

Spring Cloud针对服务注册与发现,进行了一层抽象,并提供了三种实现:
1.Eureka(支持的最好)
2.Consul
3.Zookeeper

Eureka作用:实现服务治理(服务注册与发现)
Eureka是Netflix开源的服务注册发现组件,服务端通过REST协议暴露服务,提供应用服务的注册和发现的功能。所有的Eureka服务都被称为实例(instance)。Eureka服务又分为两类角色:Eureka Server(服务器,注册中心)和Eureka Client(客户端,注册、拉取服务)

(1)Eureka Server服务端

Eureka服务端用作服务注册中心(注册服务)。支持集群部署

Eureka Server提供服务注册服务:各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到

(2)Eureka Client客户端

Eureka Client是一个Java客户端,用来处理服务注册与发现,简化与Eureka Server服务器的交互

Eureka-Client分类两类
1.Application Provider(生产者,服务提供者)
服务提供者。内嵌Eureka-Client,它向Eureka-Server注册自身服务、续约、下线等操作

2.Application Consumer(消费者,服务消费者)
服务消费者。内嵌Eureka-Client,它从Eureka-Server获取服务列表,分为全量获取和增量获取

轮询负载均衡器
客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,Eureka Client将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)

服务故障切换支持
Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡

注意:Application Provider和Application Consumer只是角色,同一个服务即可以是服务的提供者,又可以是服务的消费者。甚至,在注册中心的集群环境下,Eureka Server既可以Eureka Server,又可以是Eureka Client。Eureka Server作为Eureka Client是向其它Eureak Server同步消息(集群)


Eureka执行原理

Eureka采用C-S设计架构。Eureka Server作为服务注册功能的服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。Spring Cloud的一些其他模块(比如Zuul)就可以通过Eureka Server来发现系统中的其他微服务,并执行相关的逻辑

在应用启动时,Eureka客户端向服务端注册自己的服务信息,同时将服务端的服务信息缓存到本地。客户端会和服务端周期性的进行心跳交互,以更新服务租约和服务信息

Netflix Eureka是Spring Cloud的服务发现模块(Eureka默认端口:8761)。一个RESTful服务,用来定位运行在AWS地区(Region)中的中间层服务

客户端启动后,Jar中的定时任务会自动启动,定时向注册中心发送,客户端信息
注册中心也会通过定时任务查询各个客户端,查询没有反应,则会从服务器的注册列表中删除
在这里插入图片描述

1.注册中心(Eureka Server)

服务注册中心(可以是一个集群),对外暴露自己的地址

2.服务提供者(Application Service)

启动后向Eureka注册自己信息(地址,提供什么服务)

3.客户端消费者(Application Client)

向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新

4.心跳(renew,续约)

服务提供者定期通过http方式向Eureka刷新自己的状态


Eureka解决了什么问题?

模拟微服务,需要对外暴露自己的地址。而Consumer(调用者)需要记录服务提供者的地址。将来地址出现变更,还需要及时更新。这在服务较少的时候并不觉得有什么,但是在现在日益复杂的互联网环境,一个项目肯定会拆分出十几,甚至数十个微服务。此时如果还人为管理地址,不仅开发困难,将来测试、发布上线都会非常麻烦,这与DevOps的思想是背道而驰的

Eureka解决了模拟微服务的各种问题
(1)分布式/版本化配置
(2)服务注册和发现
(3)路由
(4)服务到服务的呼叫
(5)负载均衡
(6)断路器
(7)全局锁
(8)领导选举和集群状态
(9)分布式消息传递


DevOps(开发、运维、技术保障)(Development和Operations的组合词)

(1)一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合
(2)一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠

目的:DevOps就是为了让开发、运维和QA可以高效协作的流程。(可以把DevOps看作开发、技术运营和质量保障(QA)三者的交集)


Eureka架构中的三个核心角色

①服务注册中心

Eureka的服务端应用,提供服务注册和发现功能

②服务提供者

提供服务的应用,可以是Spring Boot应用,也可以是其它任意技术实现,只要对外提供的是Rest风格服务即可

③服务消费者

消费应用从注册中心获取服务列表,从而得知每个服务方的信息,知道去哪里调用服务
Eureka Client只会向一个Server节点进行注册(心跳、状态改变等类似),注册失败时才会尝试下一个Server节点


Eureka执行流程?

Eureka负责管理、记录服务提供者的信息。服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合需求的服务拉取下来。同时,服务提供方与Eureka之间通过“心跳”机制进行监控,当某个服务提供方出现问题,Eureka自然会把它从服务列表中剔除。这就实现了服务的自动注册、续约、发现、状态监控
在这里插入图片描述

1.服务注册

在Eureka Client(服务提供者)启动的时候,将自身的服务的信息发送到Eureka Server(注册中心),包括比如IP地址、端口、运行状况指示符URL、主页等

在DiscoveryClient类有一个服务注册的方法register(),该方法是通过Http请求向Eureka Client注册。 如果需要向Eureka Server注册,则开启注册,同时开启了定时向Eureka Server服务续约的定时任务

Eureka Client启动之后,不是立即向Eureka Server注册的,而是有一个延迟向服务端注册的时间。通过跟踪源码,可以发现默认的延迟时间为40秒

首次注册

(1)服务提供者(Eureka Client)在启动会向Eureka Server注册信息(包括服务名(Eureka Service Id)、service id、ip、port、心跳周期等),EurekaServer获取注册请求,将服务实例信息存入到读写缓存中
(2)服务消费者根据Eureka Service id向Eureka Server获取要访问服务的注册信息,第一次请求会一次性拉取对应Eureka service id的全部服务实例信息
(3)Eureka Server收到请求后,会首先在只读缓存查找,如果找到则直接返回,否则再查找读写缓存。如果找到则将再存入到只读缓存中,然后返回查找结果
(4)服务消费者将获取到的服务实例信息缓存到本地,在使用时根据算法从N个服务中中选取一个服务并向这个服务发送请求

Eureka Server缓存(两种)

(1)只读缓存
永不过期。但是可能存在过期数据。此时为了保证只读数据的准确性,会有个定时器定时同步两个缓存,然后将状态变化的服务实例添加到“最近租约变更记录队列”。执行频率默认30s

(2)读写缓存
每次有服务实例状态变化(如注册服务、下线等)只会更新读写缓存

为了提高实时性,可以关闭只读缓存。
“最近租约变更记录队列”里的数据也有有效期,默认为180s。
(1)当有注册、状态变更、下线时,会将创建最近租约变更记录加入此队列中
(2)用于注册信息增量获取
(3)后台任务定时顺序扫描队列,当数据最后更新时间超过一定时长后进行移除

#是否开启只读请求响应缓存(ResponseCache)
#响应缓存机制目前使用两层缓存策略:优先读取只读缓存,读取不到后读取固定过期的读写缓存
eureka.server.use-read-only-response-cache: true

#只读缓存更新频率,单位:毫秒
#只读缓存定时更新任务只更新读取过请求 ,因此虽然永不过期,也会存在读取不到的情况。
eureka.server.response-cache-update-interval-ms: 30s

#读写缓存写入后过期时间,单位:秒。
eureka.server.response-cache-auto-expiration-in-seconds: 180s

#移除队列里过期的租约变更记录的定时任务执行频率,单位:毫秒。默认值 :30 * 1000 毫秒。
eureka.server.delta-retention-timer-interval-in-ms: 30s

#租约变更记录过期时长,单位:毫秒。默认值:3 * 60 * 1000 毫秒。
eureka.server.retention-time-in-m-s-in-delta-queue: 180s

2.服务心跳/续约

Eureka客户端(服务提供者)会每隔30秒发送一次心跳来续约(默认)。通过续约来告知Eureka Server该Eureka客户仍然存在,没有出现问题

正常情况下,Eureka Server收到心跳后,会更新对应的服务实例信息,如果服务的状态有变化则将实例的变化加入到“最近租约变更记录队列”中

Eureka Server有个实例过期清理定时器。如果在指定时间内没有收到心跳(默认90s),则认为服务已经下线,会从读写缓存中移除此实例,将并此变化更新“最近租约变更记录队列”

通常建议将存活的最长时间设置为3个心跳时间,建议不要更改续约间隔

eureka.instance.lease-renewal-interval-in-seconds:10    
#客户端配置 ,eureka客户端需要向eureka服务器发送心跳的频率(Spring Cloud默认该配置是30s)

eureka.instance.lease-expiration-duration-in-seconds:30   
#客户端配置,eureka服务器在接收到最后一个心跳之后等待的时间,然后才能从列表中删除此实例(Spring Cloud默认该配置90s)

3.客户端从服务器获取注册列表信息

Eureka客户端从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用

服务消费者有个定时任务会定时去更新服务实例信息/注册列表信息(默认每30秒钟更新一次,从服务端查询)
(1)第一次全量拉取服务实例,会读取所有的实例信息
(2)之后使用增量拉取服务实例信息。Eureka Server根据“最近租约变更记录队列”,告诉请求方哪些服务实例有变化,只返回变化的实例信息。客户端根据返回的增量信息更新本地缓存。也可以禁用增量获取服务实例实例,每次使用全量获取服务实例信息

#是否禁用增量获取服务实例注册信息
eureka.disableDelta: false

每次返回注册列表信息可能与Eureka客户端的缓存信息不同,Eureka客户端自动处理。
如果由于某种原因导致注册列表信息不能及时匹配,Eureka客户端则会重新获取整个注册表信息


4.客户端服务下线

Eureka客户端在程序关闭时向Eureka服务器发送取消请求。发送请求后,该客户端实例信息将从服务器的实例注册表中删除

服务实例下线(两种)
(1)主动下线
在服务实例结束前,主动通知Eureka Server,在默认配置下,此时服务消费者最长在30s左右知道此服务已经下线

(2)被动下线
服务进度崩溃/网络异常,此时服务消费者最长在(3次心跳 + 一次刷新频率30s,共约120s左右)内知道此服务已经下线


5.服务端剔除客户端服务

在默认的情况下,当Eureka客户端连续90秒没有向Eureka服务器发送服务续约,即心跳。Eureka服务器会将该服务实例从服务注册列表删除(服务剔除)


6.自我保护

自我保护机制的工作机制是如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制,此时会出现以下几种情况:

(1)Eureka Server不再从注册列表中移除因为长时间没收到心跳而过期的服务。即不再剔除注册列表的信息

(2)Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用

(3)当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中

(4)如果是Eureka Server自身的网络问题,导致Eureka Client的续约不上,Eureka Client的注册列表信息不再被删除

(5)直到心跳回复正常后退出自我保护模式

#是否开启自我保护机制,默认为true|开启。
eureka.server.enable-self-preservation=false 
#自我保护系数(默认0.85)
eureka.server.renewal-percent-threshold=0.85
#扫描失效服务时间间隔(单位毫秒,默认60*1000)60秒
eureka.server.eviction-interval-timer-in-ms=60000
#设置Eureka Server同步失败的等待时间,默认5分钟,在这期间它不向客户端提供服务注册信息
eureka.server.wait-time-in-ms-when-sync-empty=5
#设置eureka server同步失败的重试次数,默认为5次
eureka.server.number-of-replication-retries=5

(6)Eureka宁可保留也许已经宕机了的client端,也不愿意将可以用的client端一起剔除
因为微服务跨进程调用,导致网络通信故障、网络分区故障,接收不到正常的续约/心跳。Eureka Server注销没有问题体的服务实例。导致大部分的服务不可用(服务明明没有问题)
自我保护机制就是为了解决上面问题。如果开启自我保护机制,服务就不会自动剔除了

7.Eureka默认使用Ribbon做负载均衡


搭建高可用的Eureka集群(了解)

Eureka Client集群注册机制?

例如:定义四个Erueka Server,端口分别为8761、8762、8763、8764
通过源码分析,当Eureka Client向Eureka Server发起注册请求的时候(根据defaultZone寻找Eureka Server列表),如果有一次请求注册成功(8761),那么后续就不会在向其他Eureka Server发起注册请求。,如果该Eureka Server的状态是down,那么它会将该Server保存到quarantineSet这个Set集合中,然后访问下一个(8762)Eureka Server。注册还不成功则继续(8763)

如果所有Erueka Server的状态是down,此时除了会将其保存到quarantineSet这个Set集合中之外,还会跳出本次循环。从而结束此次注册过程

Eureka Server服务器同步机制?

多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息

为了提高高可用,Eureka提供集群功能。不仅Eureka Client端可以集群,做为注册中心的Eureka Server也可以集群

1.Eureka Server集群(服务器)

多个Eureka Server相互注册,组成一个集群

Eureka Server服务之间同步
(1)每个Eureka Server注册的消息发生变化时,会各个服务之间定时同步,中间过程每个服务的数据可能不一致,但是最终会变得一致
(2)Eureka Server集群之间的状态是采用异步方式同步的,所以不保证节点间的状态一定是一致的,不过基本能保证最终状态是一致的

2.Eureka Client集群(客户端)

多个Eureka Client进程向注册中心注册的Eureka Service Id(服务名)相同,则被认为是一个集群
也就是defaultZone相同

集群重要类(PeerAwareInstanceRegistryImpl)

com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl
为了保证集群里所有Eureka Server节点的状态同步。实现了复制实例注册,还能复制给临节点的功能

所有操作都会同步到集群的所有服务上
(1)服务注册(Registers)
(2)服务更新(Renewals)
(3)服务取消(Cancels)
(4)服务超时(Expirations)
(5)服务状态变更(Status Changes)

一个Eureka Server在收到了Client的注册等信息时,会挨个通知其他Eureka Server临节点,复制的流程图也就是下面这个样子
在这里插入图片描述

super.register(info, leaseDuration, isReplication)
// 把实例信息保存到自己的内存中,重点看replicateToPeers方法,在这个方法中,有个for循环遍历了所有的Eureka Server临节点,然后向他们复制这些信息

高可用(High Availability)

系统架构设计中必须考虑的因素之一。通常指:通过设计减少系统不能提供服务的时间

设计系统的可用性,最重要的是满足用户的需求。系统的失败只有当其导致服务的失效性足以影响到系统用户的需求时才会影响其可用性的指标。用户的敏感性决定于系统提供的应用
例如:在一个能在1秒钟之内被修复的失败在一些联机事务处理系统中并不会被感知到,但如果是对于一个实时的科学计算应用系统,则是不可被接受的

系统的高可用性设计决定于应用。例如:如果几个小时的计划停机时间是可接受的,也许存储系统就不用设计为磁盘可热插拔的。反之,可能就应该采用可热插拔、热交换和镜像的磁盘系统。所以涉及高可用系统需要考虑:
(1)决定业务中断的持续时间。根据公式计算出的衡量HA的指标,可以得到一段时间内可以中断的时间。但可能很大量的短时间中断是可以忍受的,而少量长时间的中断却是不可忍受的
(2)在统计中表明,造成非计划的宕机因素并非都是硬件问题。硬件问题只占40%,软件问题占30%,人为因素占20%,环境因素占10%。高可用性系统应该能尽可能地考虑到上述所有因素
(3)当出现业务中断时,尽快恢复的手段

如何衡量高可用性?

可用性通常表示为一个百分比,表示在给定时间段内特定系统或组件的正常运行时间,其中100%的值表示系统永不失效
例如:在一年的时间内保证99%可用性的系统最多可以有3.65天的停机时间(1%)

这些值是根据几个因素计算的
(1)计划维护周期
(2)非计划维护周期
(3)从可能的系统故障中恢复的时间

目前大部分企业的高可用目标是4个9,也就是99.99%,也就是允许这台系统的年停机时间为52.56分钟

高可用目标:消除基础架构中的单点故障
单点定义:技术堆栈中的某个组件,如果它变得不可用,将导致服务中断。因此,应用程序中没有冗余的正常功能的部件被认为是单一故障点
要消除单点故障,必须为堆栈的每一层做好冗余准备

如何保障系统的高可用?

单点是系统高可用的大敌,单点往往是系统高可用最大的风险和敌人,应该尽量在系统设计的过程中避免单点。只有一个单点,挂了服务会受影响;如果有冗余备份,挂了还有其他backup能够顶上

高可用保证的原则:“集群化”或者“冗余
冗余:①多余的不需要的部分、②人为增加重复部分

保证系统高可用,架构设计的核心准则是:冗余。有了冗余之后,还不够,每次出现故障需要人工介入恢复势必会增加系统的不可服务实践。所以,又往往是通过“自动故障转移”来实现系统的高可用。接下来我们看下典型互联网架构中,如何通过冗余+自动故障转移来保证系统的高可用特性

(1)主从方式(非对称方式)
工作原理:主机工作,备机处于监控准备状况;当主机宕机时,备机接管主机的一切工作,待主机恢复正常后,按使用者的设定以自动或手动方式将服务切换到主机上运行,数据的一致性通过共享存储系统解决

(2)双机双工方式(互备互援)
工作原理:两台主机同时运行各自的服务工作且相互监测情况,当任一台主机宕机时,另一台主机立即接管它的一切工作,保证工作实时,应用服务系统的关键数据存放在共享存储系统中

(3)集群工作方式(多服务器互备方式)
工作原理:多台主机一起工作,各自运行一个或几个服务,各为服务定义一个或多个备用主机,当某个主机故障时,运行在其上的服务就可以被其它主机接管

容错:指当系统在运行时有错误被激活的情况下仍能保证不间断提供服务的方法和技术

容错系统在组件或子系统发生故障时继续运行;它的吞吐量可能会降低,但总体系统可用性保持不变。硬件或软件中的故障可以通过组件冗余或安全回退(如果可以在软件中进行回退)来处理。在依赖系统不可用的情况下,软件中的容错通常作为一种回退方法来实现。容错要求源自于SLA。实现依赖于硬件和软件组件,以及它们交互的规则

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未禾

您的支持是我最宝贵的财富!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值