作用:服务治理(服务注册与发现)

两个概念:

服务注册:每个服务单元向注册中心登记自己提供的服务,注册的信息含括主机与端口号、版本号、通信协议等。服务中心会维护一个服务清单,同时使用心跳的方式检测清单中的服务是否可用,若不可用则需要从服务清单中剔除,以达到排除故障服务的效果。

服务发现:微服务下的服务治理框架下,服务之间的相互调用不再通过具体的实例地址进行直接调用,而是通过向服务名发起请求调用实现。一般的逻辑是这样的,A想调用B,但是A刚开始不知道B在哪,所以A向服务中心发起请求获取B的实例地址,服务中心将所有的B实例地址给到A,A调用B的时候会从服务中心返回的B实例列表中通过某种轮询策略获取一个位置来进行服务调用,从而也就是实现了客户端负载。这里的解释只是一个思路,实际上A不会每次都去服务中心查取B地址的,并且不同的应用场景下在缓存和服务剔除机制上也会有一些不同的实现策略


Eureka的服务治理机制


Eureka服务治理基础架构下的三个核心要素

  • 服务注册中心
  • 服务提供者
  • 服务消费者

很多时候,客户端既是服务提供者又是服务消费者

服务提供者

  • 服务注册

服务提供者在启动的时候通过发送REST请求的方式将自己注册到EurecaServer上,同时带上自身元数据信息。
Eureca Server接收到这个REST请求之后,将元数据的信息储存在一个双层结构的Map中,第一层map的key为服务名,第二层的key为具体服务的实例名。

  • 服务续约(Renew)

注册完服务之后,服务提供者会维持一个心跳告诉Eureca Server :“我是一个活着的健康实例”,从而防止Eureca Server的“剔除任务”从服务列表中排除该实例。
eureka.instance.lease-renewal-interval-in-seconds:心跳任务的调用时间,默认三十秒
eureka.instance.lease-expiration-duration0in-seconds:服务时效时间,默认九十秒

服务消费者

  • 获取服务

服务消费者启动的时候会发送一个REST请求给注册中心,获取已注册的服务清单。
为了性能考虑,EurecaServer会维护一份只读的服务清单来返回给 客户端,同时该缓存清单会隔三十秒刷新一次。
eureka.client.fetch-registry:获取服务,默认为true
eureka.client.registry-fetch-interval-seconds:缓存清单的更新时间,默认三十秒

  • 调用服务

消费者获取清单之后,就可以获得服务者的实例名和元数据信息。
Ribbon默认使用轮询的方式调用,从而实现客户端负载均衡

  • 下线服务

服务实例进行正常的关闭操作时,会触发一个服务下线的REST请求给Eureca Server,注册中心将该服务状态设置为下线(DOWN),并且把下线事件传播出去。

服务注册中心

  • 服务同步

同一个服务的两个实例如果注册到不同的服务中心实例上,由于服务注册中心之间互相注册为服务,所以服务中心之间会互相转发注册请求服务给集群中的其他服务注册中心,从而实现服务注册中心之间的服务同步。

  • 失效剔除

sometime,服务实例会因为内存溢出、网络故障等不正常下线了。但是服务注册中心并没有收到“服务下线”的请求。那么为了解决这个问题,Eureca Server 在启动的时候会创建一个定时任务,默认每隔六十秒将当前清单中超时(默认九十秒)没有续约的服务剔除出去。

  • 自我保护

EurekaServer会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况,EurekaServer会将这些实例保护起来,让其不过期,但是这样会让客户端拿到已经挂掉的服务实例,这就要求客户端必须要有容错机制(请求重试、断路器等)
eureka.server.enable-self-preservation=false : 关闭保护机制


Q&A

Eureka Server 如何实现高可用?

机制:将自己作为注册中心向其他服务注册中心注册自己,这样就可以形成一组互相注册的服务注册中心。

实现: