一、前言
上两节已经搭建了一个简单的Eureka的服务注册中心和服务提供者或者服务消费者,因为有时候服务消费者也是服务提供者,这两者划分没有那么清楚的界限。本节主要介绍一些跟Eureka相关的知识。了解它们到底有什么特点和功能。
二、Eureka基础知识
本节主要将Eureka分为基础架构和服务治理两个方向描述
2.1、基础架构
在基础架构中,Eureka主要分为服务注册中心,服务提供者和服务消费者。
2.2、服务治理机制
先来看一下很基础的服务治理机制的简单示意图:
根据每一个的通信行为做具体介绍:
2.2.1、服务提供者
根据上图,服务提供的基础功能分为:(1)服务注册;(2)服务续约;(3)服务下线
(1)服务注册
服务提供者在启动的时候会通过REST请求向服务注册中心,同时会携带上自己的一些元数据信息。服务注册中心接收到注册信息后,会将信息保存在一个双层的MAP中,第一层的key就是服务的名称,第二层的key是具体服务的实例。所以在服务提供者启动时,确保对应的参数eureka.client.register-with-eureka=true,或者这个参数不配置也行,因为其默认就是true。
(2)服务续约
注册完成以后,服务提供者会保持一个心跳给服务注册中心,告诉服务注册中心:”老子还活着,你不要抽风把我从服务实例给剔除了“,这个就叫做服务续约。
在服务续约中会有两个重要的参数:
<1>eureka.instance.lease-renewal-interval-in-seconds
这个是表示服务提供者向服务注册中心续约的时间间隔,默认是30秒
<2>eureka.instance.lease-expiration-duration-in-seconds
这个是服务过期的时间,默认是90秒
(3)服务下线
服务在运行过程中不可避免的存在重启或者升级等问题,在服务关闭期间,不希望服务注册中心将消费者的请求I分配到这个服务上,所以在服务正常关闭的时候,会发送一个REST的请求给注册中心,注册中心接受到请求以后,会把对应的服务的状态设置为DOWN,并把下线事件传播出去
其中最主要的就是服务注册和续约功能。
2.2.2、服务消费者
根据上图,服务消费者的功能主要是:(1)获取服务;(2)服务的调用
(1)获取服务
服务消费者启动的时候,会向服务注册中心发送一个REST的请求,来获取服务注册中心上的服务实例清单。Eureka Service 为了性能的考虑,自己维护了一个只读属性的缓存服务清单返回给客户端,并且缓存服务清单默认是30秒刷新一次。
为了服务消费者能够获取到服务注册中心的服务实例清单,eureka.client.fetch-registry必须设置为true,或者在配置文件中不写,因为Eureka默认其为true。
如果希望修改 缓存服务清单的刷新时间,可以通过修改参数eureka.client.registry-fetch-interval-seconds
(2)服务的调用
服务消费者人获取服务实例清单以后,自然是需要调用对应 服务。他是通过服务名称来获取服务的实例和服务相关的元数据信息,服务消费者就可以自行决定要调用哪一个服务实例。例如Ribbon就是一个典型的客户端的负载均衡的应用。
2.2.3 、服务注册中心
根据上图,服务注册中心主要特色是:(1)失效剔除;(2)自我保护机制
(1)失效剔除
有时候服务不一定是正常的下线,有很多因素导致服务不能正常工作,这个时候服务注册中心不能接收到服务的下线通知,但是一直保持维护一个无效的服务实例,会给服务消费者造成错觉,这个服务还在,能够影响请求。所以为了剔除无法提供服务的实例,Eureka Service启动的时候会启动一个定时任务,来将一段时间没有进行续约的服务剔除,默认是60秒会检查一边服务清单中超过90秒没有续约的服务,然后将其剔除。
(2)自我保护机制
在我本本地开发测试的时候,注册中心很容易出现一个EMERGENCY!的红色警告,这个是因为Eureka Service有一个自我保护的机制,Eureka Service在运行期间会统计心跳失败的比例,即是在15分钟内,是否低于85%,如果低于这个比例,Eureka Service会将当前的实例注册信息保护起来,让这些实例不过期,尽量保护这些注册信息。但是很容易造成一个问题,就是在这段保护期内,客户端很容易再次拿到已经不能提供服务的实例,出现调用失败的情况,所以一般要求客户端最好有容错机制。
可以通过参数将其自我保护机制关闭:
eureka.server.enable-self-preservation为false