Eureka的服务提供者、服务消费者和注册中心详解

一 架构图

二 服务提供者
1 服务注册
“服务提供者”在启动的时候会通过REST请求的方式将自己注册到Eureka Server上,同时带上自身服务的一些元数据信息。Eureka Server接收到这个REST请求之后,将元数据信息存储在一个双层结构Map中,其中第一层的key是服务名,第二层的key是具体服务的实例名。
在服务注册时候,需要确认一下eureka.client.register-with-eureka=true参数是否正确,该值默认为true。若设置为false将不会启动注册操作。
2 服务同步
如架构图所示,这里的两个微服务提供者分别注册到两个不同的服务注册中心上,也就是说,它们的信息分别被两个服务注册中心所维护。此时由于服务注册中心之间因互相注册为服务,当服务提供者发送注册请求到一个服务注册中心时,它会将该请求转发给集群中相连的注册中心,从而实现注册中心之间的服务同步。通过服务同步,两个服务提供者的服务信息就可以通过这两台服务注册中心中的任意一台获取,
3 服务续约
在注册完服务之后,服务提供者会维护一个心跳用来持续告诉Eureka Server:“我还活着”,以防止Eureka Server的“剔除任务”将该服务实例从服务列表中排除出去,我们称该操作为服务续约(Renew)。
关于服务续约有两个重要属性,我们可以关注并根据需要来进行调整:
eureka.client.registry-fetch-interval-seconds=30
eureka.instance.lease-expiration-duration-in-seconds=90
eureka.client.registry-fetch-interval-seconds参数用来定义服务续约任务的调用间隔时间,默认为30秒。
eureka.instance.lease-expiration-duration-in-seconds参数用于定义服务失效时间,默认为90秒。

三 服务消费者
1 获取服务
到此,在服务注册中已经注册了一个服务,并且该服务有两个实例。当我们启动服务消费者的时候,它会发送一个REST请求给服务注册中心,来获取上面注册的服务清单。为了性能考虑,Eureka Server会维护一份只读的服务清单来返回给客户端,同时该缓存清单会每隔30秒更新一次。
获取服务是服务消费者的基础,所以必须确保eureka.client.fetch-registry=true参数没有被修改为false,该值默认为true。eureka.client.registry-fetch-interval-seconds=30表示间隔多久去拉取服务注册信息,该参数默认值为30,单位为秒。
2 服务调用
服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。因为有了这些服务实例详细信息,所以客户端可以根据自己的需要决定具体调用哪个实例,在Ribbon中默认采用轮询的方式进行调用,从而实现客户端的负载均衡。
对于访问实例的选择,Eureka中有Region和Zone的概念,一个Region中可以包含多个Zone,每个服务客户端需要注册到一个Zone中,所以每个客户端对于一个Region和一个Zone。在进行服务调用的时候,优先访问同处一个Zone中服务提供方,若访问不到,就访问其他的Zone。
3 服务下线
在系统运行过程中必然会面临关闭或重启服务的某个实例的情况,在服务关闭期间,我们自然不希望客户端会继续调用关闭了的实例。所以客户端程序中,当服务实例进行正常的关闭操作时,它会触发一个服务下线的REST请求给Eureka Server,告诉服务注册中心:“我要下线了”。服务端在接收到请求之后,将该服务状态设置为(DOWN),并把该下线事件传播出去。

四 注册中心
1 失效剔除
有些时候,我们的服务实例并不一定会正常下线,可能由于内存溢出,网络故障等原因使得服务不能正常工作,而服务注册中心并未收到“服务下线”的请求。为了从服务列表中将这些无法提供服务的实例剔除,Eureka Server在启动时候会创建一个定时任务,默认每隔一段时间(默认60秒)将当前清单中超时(默认为90秒)没有续约的服务剔除出去。
2 自我保护
当我们在本地调试基于Eureka的程序的时候,基本都会碰到一个问题,在服务注册中心的信息面板中出现红色警告信息。
实际上,该警告就是触发了Eureka Server的自我保护机制。服务注册到Eureka Server之后,会维护一个心跳连接,告诉Eureka Server自己还活着。Eureka Server在运行期间,会统计心跳失败比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息包含起来,让这些实例不会过期,尽可能包含这些注册信息。但是,在这段保护期内实例若出现了问题,那么客户端很容易拿到实际已经不存在的服务实例,会出现调用失败的情况,所有客户端必须要有容错机制,比如可以使用请求重试。断路器等机制。
由于本地调试很容易触发注册中心的保护机制,这会使得注册中心维护的服务实例不那么准确。所以,在本地进行开发的时候,可以使用eureka.server.enable-self-preservation=false参数来关闭保护机制,以确保注册中心可以将不可用的实例正确剔除。

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/81040822