服务治理机制:
在体验了eureka通过简单的注解配置就是实现了强大的服务治理功能,我们来了解下eureka基础架构中各个元素的一些通信行为,以此来理解eureka实现的服务治理体系是如何运作的。几个重要元素先理解一下:
“服务注册中心-1” 和 “服务注册中心-2” ,两者之间互相注册,相差了高可用集群的注册中心
“服务提供者例”启动两个实例,这两个实例分别只注册到一个服务注册中心。
启动两个“服务消费者”实例,也一样分别只注册到一个注册中心
根据上面的结构,我们可以来仔细了解一下各个节点之间的一些重要通信行为。
服务提供者:
服务提供者,在启动的的时候通过发送rest请求的方式,向注册中心注册自己的信息,会带上自身的一些元数据。注册中心接受到这些信息后,会将他们保存在一个双层的Mao结构中,第一个key是服务名,第二个key具体服务的实例名。
结构:(“key(服务名)”:(“key具体服务的实例名”:“元数据”))
spring.application.name=服务名
eureka.instance.hostname=服务实例名
在注册时,需要确认一下配置 eureka.client.register-with-eureka=true参数是否为true。若设置为false则不会启动注册操作
-
服务续约-心跳机制
在注册完服务之后,服务提供者会维护一个心跳来持续告诉eureka server注册中心,表明自己还活着,以防注册中心的“剔除任务”将自己从服务列表中剔除出去。我们称该机制为服务续约。
关于服务续约有两个重要的属性:
eureka.instance.lease-renewal-interval-in-seconds=30;该参数用于定义服务续约任务的调用时间间隔,默认为30秒。
eureka.instance.lease-expiration-duration-in-seconds=90;该参数用于定义服务失效的时间,默认为90秒。
-
服务同步
服务同步的作用一般是在有注册中心是集群的情况下,注册中心集群是多个注册中心相互的注册为服务。当服务提供者通过rest请求向注册中心注册的时候,如果有检测到有其他的注册中心,它会将请求转发到其他相连的注册中心,从而实现注册中心之间的服务同步。通过服务同步,服务提供者的服务信息就能被任何一台注册中心调用到。
服务消费者
-
获取服务
当我们启动服务消费者时,会向注册中心发送一个rest请求,来拉取服务清单列表,注册中心会返回一份只读的清单列表,然后服务消费者会将这个清单缓存。并且这份清单列表,会每30秒更新一次,去重新拉取。
获取服务是服务消费者的基础,所以必须确保eureka.client.fetch-registry=true参数没有被修改成false,该值默认为true。若希望修改缓存清单的更新时间,可以通过eureka.client.registry-fetch-interval-seconds=30参数进行修改,该参数默认为30,单位为秒。
-
服务调用
服务消费者获取到服务清单后,调用的时候通过服务名,就能拿到服务实例和元数据信息。因为有这些详细的元数据信息,我们可以根据需求调用那个服务提供者实例。在ribbon中会默认采用轮询的方式进行调用,从而实现客户端的负载均衡。
对于访问实例的选择,eureka中有region和zone的概念,一个region中可以包含多个zone,每个服务客户端需要被注册到一个zone中,所以每个客户端对应一个region和一个zone。在进行服务调用的时候,优先访问同处一个zone中的服务提供方,若访问不到,就访问其他的zone。
-
服务下线
在系统运行过程中必然会面临关闭或重启服务的某个实例的情况,在服务关闭期间,我们自然不希望客户端会继续调用到被关闭的实例。所以在客户端程序中,当服务实例进行正常的关闭操作时,它会触发一个服务下线的rest请求给eureka server注册中心,告诉服务注册中心:“我要下线了”。服务端在接收到请求之后,将该服务状态置为下线(down),并把该下线事件传播出去。然后注册中心之间服务同步就会都知道该服务客户端已下线。
服务注册中心:
-
失效剔除机制
有些时候我们的服务实例并不一定是正常下线,有可能是内存溢出、网络故障等问题使得服务不能正常工作,而服务注册中心没有收到“服务下线”的请求。为了从服务列表中将这些无法提供服务的实例剔除掉,eureka server注册中心在启动的时候会创建一个定时任务,默认每隔一段时间(60秒)将当前清单中超时(默认为90秒)没有续约的服务剔除出去。
-
自我保护
当我们在本地调试eureka时,基本上会碰到这样一i个情况,在服务注册中心的信息面板中出现红色警告:
实际上,该警告就是出发了自我保护机制。之前说过,服务注册到eureka server注册中心之后,会维护一个心跳机制,来告诉eureka server自己还活着。eureka server 注册中心在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况,eureka server会将当前的实例注册信息保护起来,让这些实例不会过期,经可能的保护这些信息。但是,在这段保护期间若实例出现问题,那么客户端很容易拿到实际已经不存在的服务实例,会出现调试失败的情况,所有客户端必须要有容错机制。比如可以使用请求重试、断路器等机制。
由于本地调试很容易就出发了注册中心的保护机制,这会使得注册中心维护的服务实例不那么准确。所以我们在本地开发的时候,可以使用
eureka. server.enable-self-oreservation=false;关闭保护机制,确保将不可用的实例剔除。