服务治理:
主要用来实现各个微服务实例的自动化注册与发现。
*服务注册:在服务治理框架中,通常都会构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机与端口号,版本号,通信协议等一些附加信息告知注册中心,注册中心按服务名分类组织服务清单。
另外,服务注册中心还需要以心跳的方式去检测清单中的服务是否可用,若不可用需要从服务清单中剔除,达到排除故障服务的效果。
*服务发现:在服务治理框架下运作,服务间的调用不再通过指定具体的实例地址来实现,而是通过向服务名发起请求调用实现。所以,服务调用方在调用服务提供方接口的时候,并不知道具体的服务实例位置。因此,调用方需要向服务注册中心咨询服务,并获取所有服务的实例清单,以实现对具体服务实例的访问。比如,服务C希望调用服务A,服务C就需要向注册中心发起咨询服务请求,服务注册中心就会将服务A的位置清单返回给服务C。当服务C要发起调用的时候,便从该清单中以某种轮询策略(负载均衡)取出一个位置来进行服务调用。
Netflix Eureka:
Eureka服务端,也称服务注册中心,支持高可用配置。它依托于强一致性提供良好的服务实例可用性,可以应对多种不同的故障场景。如果Eureka以集群模式部署,当集群中Eureka服务端,也称服务注册中心,支持高可用配置。它依托于强一致性提供良好的服务实例可用性,可以应对多种不同的故障场景。如果Eureka以集群模式部署,当集群中有分片出现故障时,那么Eureka就转入自我保护模式。允许在分片故障期间继续提供服务的发现和注册,当故障分片恢复运行时,集群中的其他分
片会把他们的状态再次同步回来。
服务端配置:
Server.port:8080 //指定服务注册中心端口
eureka.client.register-with-eureka:false //代表不向注册中心注册自己
eureka.client.fetch-registry: //代表不需要去检索服务
Eureka客户端,主要处理服务的注册与发现。客户端服务通过注解和参数配置的方式,嵌入在客户端应用程序的代码中,在应用程序运行时,Eureka客户端向注册中心注册自身提供的服务并周期性的发送心跳来更新它的服务租约。同时,它也能从服务端查询当前注册的服务信息并把它们缓存到本地并周期性的刷新服务状态。
注册服务提供者:
Spring.application.name=hello-service //为服务命名
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/ //指定服务注册中心地址
高可用注册中心:
Eureka Server的高可用实际上就是讲自己作为服务向其他服务注册中心注册自己,这样就可以形成一组相互注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。
构建一个双节点的服务注册中心集群:
服务提供方也要做相应的改动:
Eureka.client.serviceurl.defaultZone=http://peer:1111/eureka/,http://peer2:1112/eureka/
这样,服务就同时注册到了peer1和peer2上,若断开peer1,由于compute-service同时也向peer2注册,因此在peer2上的其他服务依然能访问heel-service,从而实现了服务注册中心的高可用。
Eureka.instance.prefer-ip-address=true //true使用IP地址来定义注册中心地址,false使用主机名
服务发现与消费:
服务消费者主要完成两个目标:发现服务以及消费服务。其中发现服务的任务有Eureka的客户端完成,而消费服务的任务有Ribbon完成。Ribbon是一个基于TTP和TCP的客户端负载均衡器,它可以在通过客户端配置的ribbonServerList服务端列表去轮询访问已达到均衡负载的作用。在主类中通过@EnableDiscoveryClient注解让该应用注册为Eureka客户端应用,以获得服务发现的能力,同时在该主类中创建RestTemplate的Spring Bean实例,并通过@LoadBalanced注解开启客户端负载均衡。
Eureka详解
Eureka服务治理体系中的三个核心角色:
服务注册中心:Eureka提供的服务端,提供服务注册与发现的功能
服务提供者:提供服务的应用,可以是Spring Boot应用,也可以是其他技术平台且遵循Eureka通信机制的应用,它将自己提供的服务注册到Eureka,以供其他应用发现。
服务消费者:消费者应用从服务注册中心获取服务列表,从而使消费者可以知道去何处调用其所需要的服务。
很多时候,客户端既是服务提供者也是服务消费者。
服务治理机制:
服务提供者
服务注册
“服务提供者”在启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上,同时带上自身服务的一些元数据信息。Eureka Server接收到这个REST请求之后,将元数据信息存储在一个双层结构Map中,其中第一次的key是服务名,第二次的key是具体服务的实例名。
服务同步:
如上图架构图所示,两个服务提供者分别注册到了两个不同的服务注册中心上,它们的信息分别被两个服务注册中心所维护。由于服务注册中心之间相互注册为服务,当服务提供者发送注册请求到一个服务注册中心时,它会将该请求转发给集群中相连的其他注册中心,从而实现注册中心之间的服务同步。通过服务同步,两个服务提供者的服务信息就可以通过这两台服务注册中心的任意一台获取到。
服务续约:
在注册完服务之后,服务提供者会维护一个心跳用来持续告诉Eureka Server:“我还活着”,以防止Eureka Server的“剔除任务”将该服务实例从服务列表中排除出去,称该操作为服务续约(Renew)。
关于服务续约有两个重要属性,我们可以关注并根据需要来进行调整:
eureka.instance.lease-renewal-interval-in-seconds = 30 //定义服务续约任务的调用间隔时间,默认30s
eureka.instance.lease-expiration-duration-in-seconds = 90 //定义服务失效的时间,默认为90s
服务消费者
获取服务
当启动服务消费者的时候,它会发送一个REST请求给服务注册中心,来获取上面注册的服务清单。为了性能考虑,Eureka Server会维护一份只读的服务清单来返回给客户端,同时该缓存清单会每隔30s更新一次。
eureka.client.fetch-registry = true // 设置能否获取服务
eureka.client.registry-fetch-interval-seconds = 30 //缓存清单更新时间设置
服务调用
服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。因为有这些服务实例的详细信息,所以客户端可以根据自己的需要决定具体调用哪些实例,在Ribbon中会默认采用轮询的方式进行调用,从而实现客户端的负载均衡。
对应访问实例的选择,Eureka中有Region和Zone的概念,一个Region中可以包含多个Zone,每个服务客户端需要被注册到一个Zone中,所以每个客户端对应一个Region和一个Zone。在进行服务调用的时候,优先访问同处一个Zone中的服务提供方,若访问不到,就访问其他的Zone。
服务下线
在客户端程序中,当服务实例进行正常的关闭操作(关闭或者重启服务)时,它会出发一个服务下线的REST请求给Eureka Server,告诉服务注册中心:“我要下线了”。服务端在接收到请求之后,将该服务妆台置为下线(DOWN),并把该下线事件传播出去。
服务注册中心
失效剔除
有时候,服务实例并不一定会正常下线,可能由于内存溢出,网络故障等原因使得服务不能正常工作,而服务注册中心并未收到“服务下线”的请求。为了从服务列表中将无法提供服务的实例剔除,Eureka Server 在启动时会创建一个定时任务,默认每隔一段时间(默认60s)将当前清单中超时(默认90s)没有续约的服务剔除出去。
自我保护
服务注册到Eureka Server之后,会维护一个心跳连接,告诉Eureka Server自己还活着。Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(单机调试很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,让这些实例不会过期,尽可能保护这些注册信息。但是,在这段保护期间内实例若出现问题,客户端很容易拿到实际已经不存在的服务实例,会出现调用失败的情况,所以客户端必须要有容错机制,比如可以使用请求重试,断路器等机制。
在本地开发的时候,可以使用eureka.server.enable-self-preservation=false来关闭保护机制,以确保注册中心可以将不可用的实例正确剔除。
配置详解
在Eureka的服务治理体系中,主要分为服务端和客户端,服务端为服务注册中心,客户端为各个提供接口的微服务应用。当构建了高可用的注册中心后,该集群中所有的微服务应用和后续将要介绍的基础类应用(入配置中心,API网关等)都可以视作该体系下的一个微服务(Eureka客户端)。服务注册中心也是一样,只是高可用环境下的服务注册中心除了作为客户端之外,还为集群中的其他客户端提供服务注册的特殊功能。
Eureka客户端的配置主要分为以下两个方面:
1. 服务注册相关的配置信息,包括服务注册中心的地址,服务获取的间隔时间,可用区域等。
2. 服务实例相关的配置信息,包括读物实例的名称,IP地址,端口号,健康检查路径等。
服务注册类配置
指定注册中心:通过eureka.client.serviceUrl参数实现,该参数配置值存储在HahMap类型中,并且设置了一组默认值,默认值key为defaultZone,value为http://localhost:8761/eureka/。(配置多个服务注册中心用逗号分隔)
其他配置:
服务实例类配置:
元数据:元数据是Eureka客户端在向服务注册中心发送注册请求时,用来描述自身服务信息的对象,其中包含了一些标准化的元数据,比如服务名称,实例名称,实例IP,实例端口等用于服务治理的重要信息;以及一些用于负载均衡策略或是其他特殊用途的自定义元数据信息。