1 Spring Cloud Eureka服务治理(下)

注:此随笔为读书笔记。《Spring Cloud微服务实战》,想学习Spring Cloud的同伴们可以去看看此书,里面对源码有详细的解读。

  上篇主要介绍了什么是微服务以及微服务治理的简单实现,如微服务注册中心的实现、微服务注册的实现、微服务的发现和消费的实现、微服务注册高可用的实现。本篇主要介绍一下微服务治理机制。服务治理基础架构有是三个核心要素:服务注册中心、服务提供者、服务消费者,服务提供者一般执行服务注册、服务同步、服务续约任务,服务消费者会执行获取服务、服务调用、服务下线任务,服务注册中心会执行失效剔除、自我保护任务。下面一一理解。

场景:

  有两个服务注册中心,互相注册组成高可用集群;

  服务提供者启动两个实例,一个注册在注册中心1中,一个注册在注册中心2中;(疑问:这里我试了,服务只指向一个注册中心,只启动一个实例,两个注册中心都会有刚启动的服务,这应该也算服务同步吧)

  有两个服务消费者,一个指向注册中心1中,一个指向注册中心2中。

1.服务提供者

1.服务注册

  服务提供者在启动的时候会发送REST请求将自己注册到注册中心,同时带上了自身服务的一些元数据信息。注册中心接收到请求后,将元数据信息存储在一个双层结构Map中,其中第一层的Key是服务名,第二层的Key是具体服务的实例名。如Ribbon负载均衡的例子中,一个服务有多个实例的情况。

2.服务同步

  由于服务注册中心之间互相注册为服务,当服务提供者发送注册请求到其中一个注册中心时,它会将请求转发给集群中相连的其他注册中心,此时集群中所有的注册中心都会注册该服务实例,从而实现注册中心之间的服务同步。通过服务同步,消费者就可以通过这两个注册中心的任意一个获取到两个服务提供者的服务信息。

解释:哪些服务是被服务A同步的呢?

  即各个注册中心中和服务A的服务名、端口号都相同的服务。

注册中心1:

注册中心2:

3.服务续约

  在服务注册完之后,服务提供者会维护一个心跳来告诉注册中心自己还活着,以防止注册中心的“剔除任务”将该服务实例从服务列表剔除,我们把该操作称为续约。

eureka.instance.lease-renewal-interval-in-seconds=30  #服务续约任务的调用间隔时间,默认为30秒
eureka.instance.lease-expiration-duration-in-seconds=90 #定义服务失效的时间,默认90秒

 2.服务消费者

1.获取服务

  到这里,服务注册中心都注册了一个服务,并且该服务都拥有两个服务实例。当我们启动服务消费者的时候,会发送REST请求给注册中心,来获取注册中心的服务清单。为了性能考虑,注册中心会维护一份只读的服务清单返回给客户端,该缓存清单默认30秒更新一次。

eureka.client.fetch-register=true  #确定会获取注册中心的服务清单
eureka.client.fetch-register-interval-seconds=30 #缓存清单的更新时间,默认30秒

2.服务调用

  服务消费者获取到服务清单后,通过服务名可以获得服务提供的服务实例名和该实例的元数据信息,由于服务实例有详细的元数据信息,因而客户端可以根据自己的需要调用哪个服务实例,在Spring Cloud Ribbon中采用轮询的方式进行调用,从而实现客户端的负载均衡。

3.服务下线

  当服务挂掉后,会触发下线的REST请求给注册中心,注册中心收到请求后会将该服务的状态设置成“DOWN”,并把下线事件传播出去。

3.服务注册中心

1.失效剔除

   有些时候我们的服务不会正常下线,有可能是内存溢出、网络故障等原因导致服务不可用,而注册中心并外收到服务下线请求。为了从服务列表中将无法提供的服务正确剔除,注册中心在启动的时候会创建一个定时任务,每隔一段时间(默认60秒)将当前服务清单中超时(默认90秒)没有续约的服务剔除。

2.自我保护

  服务注册到注册中心后,会维护一个心跳连接,告诉注册中心自己还活着。注册中心在运行期间,会统计该服务心跳失败的比例,15分钟低于85%(在开发环境,debug调试的时候很容易出现;生成环境网络不稳定会导致) 的情况下,注册中心会将服务信息保存起来,让这些服务实例不会过期,更不会剔除服务实例。但是这段时间服务实例若出现问题,那么消费者很容易拿到不可用的服务实例,从而出现调用失败的情况。所以客户端需要有容错机制,比如使用请求重试、断路由等机制。

  我们公司内部产品遇到过这种情况,用户登录系统时有时候超时最终返回错误页面,有时候就可以正常登录。当时确定的影响因素是网络非常不稳定,那么在网络稳定性问题解决之前,服务需要正常访问,当时采用的方案是请求重试机制,一般在第二次请求时便会请求成功,而且速度和网络良好的情况差不多。qa那边也会认为这个问题解决了。当然,网络正常后,服务也会正常访问。现在看来,原来是注册中心的自我保护机制导致的。解决方案就是请求重试和断路由等机制了。

  由于在本地开发的时候,debug调试,会经常引起注册中心自我保护机制,所以,在本地开发的时候可以关闭注册中心的自我保护机制,以确保注册中心将不可用的服务立即剔除。

eureka.server.enable-self-preservation=false #关闭自我保护机制

 

posted @ 2017-09-22 15:07  展云  阅读(1162)  评论(1编辑  收藏  举报