Eureka的基础架构
Eureka的服务治理机制
服务提供者
1、服务注册
注:在服务注册时,需要确认配置文件中eureka.client.register-with-eureka=true是否正确,该值默认为true。若设置为false将不会启动注册操作。
2、服务同步
当两个服务中心互相注册为服务时,当服务提供者发送请求到一个服务注册中心,这个服务注册中心会将该请求转发给集群中相连的其他注册中心,从而实现注册中心之间的服务同步。通过服务同步,两个服务提供者的服务信息就可以通过这两台服务注册中心中的任意一台获取到。
3、服务续约
在注册完服务之后,服务提供者会维护一个心跳来告诉Eureka Server:“我还活着”,以防止Eureka Server的“剔除任务”将该服务实例从服务列表中排除出去,我们称该操作为服务续约。
如何配置服务续约?
在中配置如下参数:
服务消费者
1、获取服务
获取服务的配置:
在中配置如下参数:
2、服务调用
服务消费者在获取服务清单之后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。
问题:服务消费者通过服务名从什么地方获取上述的信息?
3、服务下线
当服务进行正常关闭操作时,它会触发一个服务下线的REST请求给Eureka Server,告诉服务注册中心:“我要下线了”。服务中心接受到请求之后,将该服务置为下线状态。
服务注册中心
1、失效剔除
有时我们的服务可能由于内存溢出或网络故障等原因使得服务不能正常的工作,而服务注册中心并未收到“服务下线”的请求。相对于服务提供者的“服务续约”操作,服务注册中心在启动时会创建一个定时任务,默认每隔一段时间(默认为30秒)将当前清单中超时(默认为90秒)没有续约的服务剔除,这个操作被称为失效剔除。
2、自我保护
若我们在服务注册中心的信息面板出现类似上图的红色警告信息时,就表示触发了Eureka Server的自我保护机制。服务提供者注册到服务注册中心后会维护一个心跳连接,告诉Eureka Server自己还活着。Eureka Server在运行期间会统计心跳失败的比例,若该比例在15分钟之内低于85%时,Eureka Server会将当前的实例注册信息保护起来,让这些实例不过期,但在这段保护期内实例出现问题,那么客户端很容易拿到实际已经不存在的服务实例,会出现调用失败的情况,所以客户端必须要有容错机制。
由于本地调试很容易触发注册中心的自我保护机制(生产环境上通常由于网络不稳定导致),所以当我们在本地开发时,可以在中配置如下参数来关闭Eureka Server的自我保护机制,以确保注册中心可以将不可以的实例正确剔除:
配置详解
当我们构建了高可用的注册中心之后,该集群中所有的微服务应用和后续将要介绍的一些基础类应用都可以视作该体系下的一个微服务(Eureka客户端)。Eureka服务端更多的类似于一个现成的产品,大多数情况下我们不需要修改服务端的配置信息,所以我们多数是对客户端进行配置。
1、服务注册配置类
关于服务注册类的配置信息,我们可以通过查看下图所示的EurekaInstanceConfigBean类来获得比官方文档更为详尽的内容:
2、元数据
在上述的EurekaInstanceConfigBean的配置信息中有一大部分内容都是对服务实例元数据的配置。
那么什么是服务实例的元数据呢?
元数据是Eureka客户端向注册中心发送注册请求时,用来描述自身服务信息的对象,其中包含了服务名称、实例IP、实例端口等用于服务治理的重要信息;以及一些用于负载均衡或其他特殊用途的自定义信息。
在使用Spring Cloud Eureka时,所有配置信息都通过 EurekaInstanceConfigBean 进行加载,但真正进行服务注册的时候,还是会包装为如下图所示的InstanceInfo对象发送给Eureka服务端:
我们可以直接查看 InstanceInfo 类中的详细定义来了解原生Eureka对元数据的定义:
如何在中对元数据进行配置?
3、实例名配置
在Netflix Eureka的原生实现中,实例名采用主机名作为默认值,这样使得同一主机上无法启动多个相同的服务实例。所以,在Spring Cloud Eureka的配置中针对同一主机中启动多实例的情况,对实例名的默认命名做了更为合理的扩展,它采用了如下的默认规则:
如果我们在本地进行客户端的负载均衡时,需要启动同一服务的多个实例,如果我们启动同一个应用必然会产生端口冲突。我们可以在 进行如下配置来设置实例名从而解决这个问题:
4、端点配置
在 InstanceInfo 中我们可以看到一些URL的配置信息,如下图所示:
其中状态页和健康检查的URL在Spring Cloud Eureka中默认使用了 spring-boot-actuator 模块提供的 /info 端点 和 /health 端点。虽然我们在之前的示例中并没有对这些端点做具体的设置,但实际上这些URL地址的配置非常重要。
大多数情况下我们不需要修改这几个URL配置,但在一些特殊情况下,比如我们给应用设置了 context-path时,所有的 spring-boot-actuator 模块的监控端点都会增加一个前缀。所以我们就需要在 做类似如下的配置,为 /info 和 /health 端点也加上类似的前缀信息:
另外有时候为了安全考虑,也可能会修改 /info 和 /health 端点的原始路径。这个时候,我们也需要在服务端的中做一些特殊的配置,如下所示:
上面的两个配置都是使用相对路径来进行配置。由于Eureka的服务注册中心默认会以HTTP的方式来访问和暴露这些端点,因此当客户端应用以HTTPS的方式来暴露服务和监控端点时,相对路径的配置方式就无法满足需求了。所以,Spring Cloud Eureka 还提供了绝对路径的配置参数,具体示例如下所示:
5、健康检测
默认情况下,Eureka中各个服务实例的健康检测并不是通过 spring-boot-actuator 模块的 /health 端点来实现的,而是依靠客户端心跳的方式来保持服务实例的存活。默认的心跳实现方式可以有效的检查客户端进程是否正常运作,但却无法保证客户端应用能够正常提供服务。由于大多数的微服务会调用一些外部资源,比如数据库、缓存、消息代理等,如果我们的应用与这些外部资源无法联通时,实际上已经不能提供正常的对外服务了,但因为客户端心跳依然在运行,所以它还是会被消费者调用,而这样的调用并不能达到预期的结果。
那我们该如何实现更加全面的健康状态维护呢?
1)在服务端的 中引入 spring-boot-starter-actuator 模块的依赖:
2)在客户端的 中添加如下配置参数: