一、为什么需要注册中心?
在谈论这个问题之前,我们先来了解一下微服务的概念。
现在的项目越来越大,为了多人协同开发,为了提高系统并发量,为了减轻单个项目的业务重量,引入了微服务,解决以上问题。
在使用微服务中,首先需要面对的问题,就是我们在将各个业务点做了拆分、细化、独立之后,我们要考虑各个服务之间相互依赖,引用问题。
那么各个服务之间如何通信呢?
在单体服务中如果不同服务之间需要通信,一般都是服务将接口暴露,其他服务通过http进行请求调用,那么很明显,其实在微服务中也可以这样。
如果我们照搬过来,肯定不行,单体服务中一般我们都会将请求地址URL进行写死到项目/写入配置文件中,因为服务固定且不多。
但在微服务中则需要考虑的是大量的服务,且服务存在在线扩展操作,又或者服务宕机怎么办呢?所以,无法照搬上面的方案。
注册中心存在的意义
为了更简便更快捷的管理应用中的每一个服务,是在分布式服务节点之间的一个纽带。
注册中心核心功能
- 服务注册与服务发现:可动态的增减服务节点,服务节点实时动态的增减后,可由注册中心通知各个服务消费者,不需要服务消费者手动更新自己本地服务提供者配置信息
- 服务配置:动态修改服务配置,并将配置推送到服务提供者和服务消费者,不需要重启服务
- 健康检查和服务摘除:主动检查服务健康状况,对于宕机服务将自动从服务列表中摘除服务节点信息
二、服务注册与服务发现基本原理
服务注册:
服务提供者启动时,将自身服务的信息(服务提供者IP地址、端口、配置信息等)保存在注册中心中,以便提供其他服务消费者使用
服务发现:
服务消费者启动时,会根据本身依赖的配置信息,向注册中心获取所需服务提供者的信息,并将服务信息缓存在本地
服务通知:
当服务提供者列表中,突然有某个服务提供者宕机,无法再提供服务时。注册中心监听到服务状态后,将该服务提供者注册信息删除,并将更新后的服务提供者列表推送都各个服务消费者,服务消费者更新本地服务列表缓存信息
三、eureka 特性
自我健康检查机制
Eureka Service 与 Eureka Client 之间使用心跳机制来确定Eureka Client的健康状态,默认情况下,服务端与客户端心跳正常,应用程序状态始终都会保持为“UP”状态
<!--健康检查依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.yml 配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
healthcheck:
enabled: true
心跳间隔配置机制
Eureka Client:
注册服务收起发送:每隔n(n=30,默认)秒向Eureka服务端发送信息,刷新注册服务
客户端告知服务端:若在n秒内没有向服务器发送信息,则服务端将其从服务列表中删除Eureka Server:
自我保护机制
注册服务周期检测:每隔n(n=90,默认)秒检测服务端是否重新注册服务,否则将服务从服务列表中清除
注册表抓取机制
1、eureka服务注册表拉取机制可以大致分为两种:1全量拉取;2、增量拉取
2、eureka server 缓存机制,在eureka server启动时,会先从本地获取服务注册表,如果获取不到则等待30s时间,再去获取
3、缓存过期策略:1、被动过期,线程任务每隔30s对比readWriteCacheMap和readOnlyCacheMap是否一致,不一致的话就将readWriteCacheMap中的数据放到readOnlyCacheMap中来;2、主动过期,服务实例有注册、下线、故障都会将readWriteMap中ALL_APPS这个key对应的缓存,给他过期掉;定时过期:每个key创建的时候都会设哥过期时间180s
4、增量拉取 server端会维护一个队列,队列里存放着最近3分钟实例变更记录信息,client来拉取增量数据时,server会将队列里的数据和类似全量注册表的hash值返回给client。client拿到返回结果,若为空则全量拉取注册表,不为空就与本地注册表对比合并,然后计算hash值并与返回的全量hash值对比,如果不一致则全量拉取注册表
自我保护措施机制
Eureka Server会实时收集每分钟各个服务提供者给回的正常心跳记录数,当有效心跳记录数少于一个最小心跳数时,Eureka Server会认为是自身服务网络出现问题,那么Eureka Server将封存服务列表,不再将服务提供者踢出列表,防止错误下架服务提供者